Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

Cách tắt Redis Caching tại thời điểm chạy nếu kết nối redis không thành công

Hãy đun sôi điều này một chút. Ứng dụng của bạn sử dụng bộ nhớ đệm (được triển khai với Redis). Nếu kết nối Redis bị cũ / bị đóng hoặc nếu không, thì bạn muốn ứng dụng bỏ qua bộ nhớ đệm và (có lẽ) đi trực tiếp vào kho dữ liệu cơ bản (ví dụ:RDBMS). Logic Dịch vụ của ứng dụng có thể trông tương tự như ...

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

Tất cả những gì quan trọng trong Tóm tắt bộ đệm của Spring core để xác định một "lỡ" Cache là giá trị trả về là null. Do đó, Spring Caching Infrastructure sau đó sẽ tiến hành gọi phương thức Service thực tế (tức là getCustomer). Hãy nhớ rằng khi trả về lệnh gọi getCustomerRepo (). Load (customerId), bạn cũng cần xử lý trường hợp Spring's Caching Infrastructure cố gắng lưu giá trị vào bộ nhớ cache.

Với tinh thần giữ cho nó đơn giản , chúng tôi sẽ làm được nếu không có AOP, nhưng bạn cũng có thể đạt được điều này bằng cách sử dụng AOP (lựa chọn của bạn).

Tất cả những gì bạn (nên) cần là một RedisCacheManager "tùy chỉnh" mở rộng triển khai SDR CacheManager, giống như ...

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

Vì vậy, nếu Redis không khả dụng, có lẽ tốt nhất bạn có thể làm là ghi lại sự cố và tiếp tục để cho phép gọi Dịch vụ xảy ra. Rõ ràng, điều này sẽ cản trở hiệu suất nhưng ít nhất nó sẽ nâng cao nhận thức rằng một vấn đề đang tồn tại. Rõ ràng, điều này có thể được gắn với một hệ thống thông báo mạnh mẽ hơn, nhưng nó là một ví dụ thô sơ về các khả năng. Điều quan trọng là, Dịch vụ của bạn vẫn khả dụng trong khi các dịch vụ khác (ví dụ:Redis) mà dịch vụ ứng dụng phụ thuộc vào, có thể đã không thành công.

Trong phần triển khai này (so với phần giải thích trước đây của tôi), tôi đã chọn ủy quyền cho việc triển khai RedisCache cơ bản, thực tế để cho phép Exception xảy ra, sau đó biết rõ có sự cố với Redis và để bạn có thể đối phó với Exception một cách thích hợp. Tuy nhiên, nếu bạn chắc chắn rằng Ngoại lệ có liên quan đến sự cố kết nối khi kiểm tra, bạn có thể trả về "null" để cho Spring Caching Infrastructure tiếp tục như thể nó là một "miss" trong Bộ nhớ cache (tức là Kết nối Redis bị lỗi ==Bỏ lỡ bộ nhớ cache, trong trường hợp này).

Tôi biết điều gì đó như thế này sẽ giúp ích cho vấn đề của bạn khi tôi đã xây dựng một nguyên mẫu tương tự của việc triển khai CacheManager "tùy chỉnh" cho GemFire ​​và một trong những khách hàng của Pivotal. Trong UC cụ thể đó, "lỡ" Cache phải được kích hoạt bởi một "phiên bản lỗi thời" của đối tượng miền ứng dụng nơi quá trình sản xuất có sự kết hợp giữa các ứng dụng khách mới hơn và cũ hơn kết nối với GemFire ​​thông qua Spring's Caching Abstraction. Ví dụ:các trường đối tượng miền ứng dụng sẽ thay đổi trong các phiên bản mới hơn của ứng dụng.

Dù sao, hy vọng điều này sẽ hữu ích hoặc cung cấp cho bạn nhiều ý tưởng hơn.

Chúc mừng!



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Java Client để kết nối ElasticCache Redis Cache Node

  2. Làm cách nào để phát hành lệnh HGET / GET cho Cơ sở dữ liệu Redis qua Node.js?

  3. Node redis nhà xuất bản chiếm quá nhiều bộ nhớ

  4. Làm cách nào để thiết lập kết nối với Redis Sentinel bằng thư viện Jedis?

  5. Kết nối với RedisToGo thông qua Node.JS