【问题标题】:How to disable Caching at runtime if Couchbase connection failed?如果 Couchbase 连接失败,如何在运行时禁用缓存?
【发布时间】:2017-10-26 07:02:34
【问题描述】:

我在这里遇到了类似的问题 - How to disable Redis Caching at run time if redis connection failed。我的应用程序在服务层使用@Cacheable 进行大部分数据库/静态资源调用。

缓存由Couchbase 支持,每当应用程序无法连接Couchbase 时,节点应用程序就会关闭。这是我们没有预料到的,我们希望在连接失败时从源系统提供数据。

我们尝试实现CacheErrorHandler,但它没有按预期工作,因为我们想要执行正在调用服务并返回响应的实际方法,而不是记录缓存失败,基本上绕过缓存,一旦 Couchbase 节点启动或建立连接,就从缓存中获取数据。

知道我们如何实现它吗?

【问题讨论】:

  • this 对这个问题的回答有什么问题?它似乎可以使用 Spring 缓存框架处理您需要的情况。
  • @DanielBickler 你提到的回答显示了如何处理缓存连接失败,但我正在寻找的基本上是绕过缓存并在连接不可用时执行方法定义,一旦建立连接就得到缓存中的数据。
  • 对不起,我试图链接到this 答案。您尝试访问缓存并处理异常的位置。如果是连接异常则返回null。
  • 对不起,忽略我的最后评论。我在手机上看它,它把我带到了错误的答案。您将如何确定连接的状态?如果您可以确定连接的状态,则可以执行类似于第一个答案的操作,即包装部分缓存并在没有连接时模拟缓存未命中。
  • @DanielBickler 感谢建议“在没有连接时模拟缓存未命中”是关键。

标签: java spring spring-mvc couchbase spring-cache


【解决方案1】:

感谢@Daniel Bickler 的建议,下面是我写的参考@John Blum answer 的实现。

CouchbaseCustomCacheManager

import java.util.Map;
import org.springframework.cache.Cache;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;

public class CouchbaseCustomCacheManager extends CouchbaseCacheManager {

    public CouchbaseCustomCacheManager(
            final Map<String, CacheBuilder> initialCaches) {
        super(initialCaches);
    }

    @Override
    public Cache getCache(String name) {
        return new CouchbaseCacheWrapper(super.getCache(name));
    }

    protected static class CouchbaseCacheWrapper implements Cache {

        private final Cache delegate;

        public CouchbaseCacheWrapper(Cache couchbaseCache) {
            this.delegate = couchbaseCache;
        }

        @Override
        public String getName() {
            try {
                return delegate.getName();
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public Object getNativeCache() {
            try {
                return delegate.getNativeCache();
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public ValueWrapper get(Object key) {
            try {
                return delegate.get(key);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public <T> T get(Object key, Class<T> type) {
            try {
                return delegate.get(key, type);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public void put(Object key, Object value) {
            try {
                delegate.put(key, value);
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        @Override
        public ValueWrapper putIfAbsent(Object key, Object value) {
            try {
                return delegate.putIfAbsent(key, value);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public void evict(Object key) {
            try {
                delegate.evict(key);
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        @Override
        public void clear() {
            try {
                delegate.clear();
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        protected <T> T handleErrors(Exception e) throws Exception {
            if (e instanceof Exception) {
                return null;
            } else {
                throw e;
            }
        }
    }

}

并将其用作:

@Bean
public CacheManager cacheManager() {
    final Map<String, CacheBuilder> cache = new HashMap<>();
    for (final String appCache : "127.0.0.1,127.0.0.2,127.0.0.3".split(",")) {
     cache.put(appCache, CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
                    "default", "")));
    }
    return new CouchbaseCustomCacheManager(cache);
}

【讨论】:

    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2020-01-07
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多