# 113. 为 redis 集群崩溃时的访问失败增加 fail silent 容错机制

上一节课,我们已经通过 hystrix command 对 redis的访问进行了资源隔离; 避免 redis 访问频繁失败或者频繁超时的时候,耗尽大量的 tomcat 容器的资源阻塞在 redis 的访问上,限定只有一部分线程资源可以用来访问 redis

如果 redis 集群彻底崩溃了,这个时候,可能 command 对 redis 的访问大量的报错和 timeout 超时, 就会触发熔断(短路)机制

那么熔断机制触发后,就会调用降级 fallback,这里使用 fail silent 策略,直接返回 null

由于比较简单,只贴出其中一个 command 的降级

@Override
protected ProductInfo getFallback() {
    return null;
}
1
2
3
4

这里为什么会选择返回 null?其实与这块架构代码实现有关。

@RequestMapping("/getProductInfo")
@ResponseBody
public ProductInfo getProductInfo(Long productId) {
    ProductInfo productInfo = cacheService.getProductInfoOfRedisCache(productId);
    log.info("从 redis 中获取商品信息");
    if (productInfo == null) {
        productInfo = cacheService.getProductInfoFromLocalCache(productId);
        log.info("从 ehcache 中获取商品信息");
    }
    if (productInfo == null) {
        // 两级缓存中都获取不到数据,那么就需要从数据源重新拉取数据,重建缓存
        // 假设这里从数据库中获取的数据
        String productInfoJSON = "{\"id\": 1, \"name\": \"iphone7手机\", \"price\": 5599, \"pictureList\":\"a.jpg,b.jpg\", \"specification\": \"iphone7的规格\", \"service\": \"iphone7的售后服务\", \"color\": \"红色,白色,黑色\", \"size\": \"5.5\", \"shopId\": 1," +
                "\"modifyTime\":\"2019-05-13 22:00:00\"}";
        productInfo = JSONObject.parseObject(productInfoJSON, ProductInfo.class);
        rebuildCache.put(productInfo);
    }
    return productInfo;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

从代码中可以看到:

  1. 先从 redis 中获取商品信息
  2. 如果没有获取到,则从 ehcache 中获取
  3. 如果 ehcache 中没有获取到,则从源服务获取

这里的多级缓存架构导致使用 fail silent 返回 null 非常合适, 当 redis 崩溃之后,触发了降级策略,在调用处(也就是上面代码中)是感知不到的, 只会说发现缓存命中率直线下降,因为全部返回了 null

当后续 redis 恢复后,短路器被关闭,又可以正常访问 redis 了,全自动