आइए इसे थोड़ा उबाल लें। आपका एप्लिकेशन कैशिंग (Redis के साथ कार्यान्वित) का उपयोग करता है। यदि रेडिस कनेक्शन पुराना/बंद या अन्यथा है, तो आप चाहते हैं कि एप्लिकेशन कैशिंग को बाईपास करे और (संभवतः) सीधे अंतर्निहित डेटा स्टोर (जैसे आरडीबीएमएस) पर जाए। एप्लिकेशन सेवा तर्क कुछ इस तरह दिख सकता है...
@Service
class CustomerService ... {
@Autowired
private CustomerRepository customerRepo;
protected CustomerRepository getCustomerRepo() {
Assert.notNull(customerRepo, "The CustomerRepository was not initialized!");
return customerRepo;
}
@Cacheable(value = "Customers")
public Customer getCustomer(Long customerId) {
return getCustomerRepo().load(customerId);
}
...
}
कैश "मिस" का पता लगाने के लिए स्प्रिंग कोर के कैशिंग एब्स्ट्रक्शन में जो कुछ मायने रखता है वह यह है कि लौटाया गया मान शून्य है। जैसे, स्प्रिंग कैशिंग इन्फ्रास्ट्रक्चर तब वास्तविक सेवा पद्धति (यानी getCustomer) को कॉल करने के लिए आगे बढ़ेगा। getCustomerRepo().load(customerId) कॉल की वापसी पर ध्यान रखें, आपको उस मामले को भी संभालना होगा जहां स्प्रिंग का कैशिंग इंफ्रास्ट्रक्चर अब मूल्य को कैश करने का प्रयास करता है।
इसे सरल रखने की भावना में , हम एओपी के बिना करेंगे, लेकिन आप एओपी (अपनी पसंद) का उपयोग करके इसे हासिल करने में सक्षम होना चाहिए।
आपको बस (चाहिए) एक "कस्टम" RedisCacheManager की आवश्यकता है जो SDR CacheManager कार्यान्वयन का विस्तार करता है, कुछ इस तरह...
package example;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
...
class MyCustomRedisCacheManager extends RedisCacheManager {
public MyCustomerRedisCacheManager(RedisTemplate redisTemplate) {
super(redisTemplate);
}
@Override
public Cache getCache(String name) {
return new RedisCacheWrapper(super.getCache(name));
}
protected static class RedisCacheWrapper implements Cache {
private final Cache delegate;
public RedisCacheWrapper(Cache redisCache) {
Assert.notNull(redisCache, "'delegate' must not be null");
this.delegate = redisCache;
}
@Override
public Cache.ValueWrapper get(Object key) {
try {
delegate.get(key);
}
catch (Exception e) {
return handleErrors(e);
}
}
@Override
public void put(Object key, Object value) {
try {
delegate.put(key, value);
}
catch (Exception e) {
handleErrors(e);
}
}
// implement clear(), evict(key), get(key, type), getName(), getNativeCache(), putIfAbsent(key, value) accordingly (delegating to the delegate).
protected <T> T handleErrors(Exception e) throws Exception {
if (e instanceof <some RedisConnection Exception type>) {
// log the connection problem
return null;
}
else if (<something different>) { // act appropriately }
...
else {
throw e;
}
}
}
}
इसलिए, यदि रेडिस अनुपलब्ध है, तो शायद सबसे अच्छा आप समस्या को लॉग इन कर सकते हैं और सेवा आमंत्रण होने देने के लिए आगे बढ़ सकते हैं। जाहिर है, यह प्रदर्शन में बाधा डालेगा लेकिन कम से कम यह जागरूकता बढ़ाएगा कि एक समस्या मौजूद है। स्पष्ट रूप से, इसे अधिक मजबूत अधिसूचना प्रणाली में जोड़ा जा सकता है, लेकिन यह संभावनाओं का एक कच्चा उदाहरण है। महत्वपूर्ण बात यह है कि आपकी सेवा उपलब्ध रहती है जबकि अन्य सेवाएं (जैसे रेडिस) जिन पर एप्लिकेशन सेवा निर्भर करती है, विफल हो सकती हैं।
इस कार्यान्वयन में (बनाम मेरी पिछली व्याख्या) मैंने अपवाद को होने देने के लिए अंतर्निहित, वास्तविक RedisCache कार्यान्वयन को सौंपना चुना, फिर पूरी तरह से जानने के लिए Redis के साथ एक समस्या मौजूद है, और ताकि आप उचित रूप से अपवाद से निपट सकें। हालांकि, यदि आप निश्चित हैं कि अपवाद निरीक्षण पर कनेक्शन समस्या से संबंधित है, तो आप स्प्रिंग कैशिंग इंफ्रास्ट्रक्चर को आगे बढ़ने के लिए "शून्य" वापस कर सकते हैं जैसे कि यह कैश "मिस" (यानी खराब रेडिस कनेक्शन ==कैश मिस, इस मामले में)।
मुझे पता है कि इस तरह से आपकी समस्या में मदद मिलनी चाहिए क्योंकि मैंने GemFire और Pivotal के ग्राहकों में से एक के लिए "कस्टम" CacheManager कार्यान्वयन का एक समान प्रोटोटाइप बनाया है। उस विशेष यूसी में, कैश "मिस" को एप्लिकेशन डोमेन ऑब्जेक्ट के "आउट-ऑफ-डेट वर्जन" द्वारा ट्रिगर किया जाना था, जहां उत्पादन में स्प्रिंग के कैशिंग एब्स्ट्रक्शन के माध्यम से जेमफायर से जुड़ने वाले नए और पुराने एप्लिकेशन क्लाइंट का मिश्रण था। उदाहरण के लिए ऐप के नए संस्करणों में एप्लिकेशन डोमेन ऑब्जेक्ट फ़ील्ड बदल जाएंगे।
वैसे भी, आशा है कि यह आपकी मदद करेगा या आपको और विचार देगा।
चीयर्स!