2017-05-25 199 views
2

我遇到類似的問題 - How to disable Redis Caching at run time if redis connection failed。我的應用程序在服務層使用@Cacheable進行大部分數據庫/靜態資源調用。如何在運行時禁用Couchbase連接失敗的緩存?

緩存由Couchbase支持,並且每當應用程序無法連接時Couchbase節點應用程序關閉。這是我們不期待的,我們希望數據在連接失敗時應該從源系統提供。

我們試圖實現CacheErrorHandler但由於我們要執行這在撥打服務電話的實際方法,並儘快返回響應,而不是記錄緩存失敗,基本上繞過高速緩存,並預期它不工作Couchbase節點啓動或連接建立從緩存中獲取數據。

任何想法我們如何實現它?

+0

這有什麼錯上[這](https://stackoverflow.com/a/29353566/1495050)答案題?它似乎處理你需要使用Spring緩存框架的情況。 –

+0

@DanielBickler你提到的答案顯示瞭如何處理緩存連接失敗,但是我尋找的基本上是繞過緩存並在連接不可用時執行方法定義,並且一旦連接建立從緩存中獲取數據。 – Arpit

+0

對不起,我試圖鏈接到[this](https://stackoverflow.com/a/29353566/1495050)的答案。您嘗試訪問緩存並處理異常的位置。如果它是連接異常,則返回null。 –

回答

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); 
}