大庆市建设中专网站,伊犁建设网站,wordpress安装上传失败,商品分类标准Redis 集群故障探测
在生产环境中#xff0c;如果 Redis 集群崩溃了#xff0c;那么会导致大量的请求打到数据库中#xff0c;会导致整个系统都崩溃#xff0c;所以系统需要可以识别缓存故障#xff0c;限流保护数据库#xff0c;并且启动接口的降级机制
降级方案设计 …Redis 集群故障探测
在生产环境中如果 Redis 集群崩溃了那么会导致大量的请求打到数据库中会导致整个系统都崩溃所以系统需要可以识别缓存故障限流保护数据库并且启动接口的降级机制
降级方案设计 我们在系统中操作 Redis 一般都是通过工具类来进行操作的假设工具类有两个 RedisCache 和 RedisLock那么通过 AOP 对这两个工具类的所有方法做一个切面如果在这两个类中执行 Redis 操作时Redis 挂掉了就会抛出异常Redis 连接失败那么我们在切面的处理方法上捕捉异常再记录下来判断是 Redis 集群挂了还是展示网络波动
判断是集群挂掉还是网络波动的话我们可以配置规则比如 30 秒内出现了 3 次 Redis 连接失败就认为 Redis 挂掉了可以使用 Hotkey 配置规则那么如何自动恢复呢可以设置 hotkey 中的缓存过期时间设置为 60 秒那么缓存过期之后会再次尝试去操作 Redis如果 Redis 恢复了就可以正常使用了如果还没有恢复会继续向 hotkey 中 set 数据切面中记录 Redis 故障代码如下
Around(redisCachePointcut() || redisLockPointcut())
public Object around(ProceedingJoinPoint point) {// 签名信息Signature signature point.getSignature();// 强转为方法信息MethodSignature methodSignature (MethodSignature) signature;// 参数名称String[] parameterNames methodSignature.getParameterNames();//执行的对象Object target point.getTarget();log.debug(处理方法:{}.{}, target.getClass().getName() , methodSignature.getMethod().getName());Object[] parameterValues point.getArgs();//查看入参log.debug(参数名:{}参数值:{}, JSONObject.toJSONString(parameterNames), JSONObject.toJSONString(parameterValues));Class returnType methodSignature.getReturnType();// 返回类型是否布尔类型boolean booleanType boolean.class.equals(returnType) || Boolean.class.equals(returnType);try {if (Objects.nonNull(JdHotKeyStore.get(redis_connection_failed))) {// 值不为空表示redis连接失败这里就不再继续请求redis了直接返回false或者nulllog.error(获取缓存失败redis连接失败直接返回 false 或者 null);if (booleanType) {return false;}return null;}return point.proceed();} catch (Throwable throwable) {log.error(执行方法:{}失败异常信息:{}, methodSignature.getMethod().getName(), throwable);/** redis连接失败不抛异常返回空值* 继续用数据库提供服务避免整个服务异常* 一分钟之内或者30秒之内出现了几次redis连接失败* 此时可以设置一个key告诉hotkeyredis连接不上了指定1分钟左右的过期时间* 下次获取缓存的时候先根据hotkey来判断redis是否异常了* hotkey在1分钟之后会删除key下次再有redis请求过来重新去看redis能否连接* 这样可以简单的实现redis挂掉之后直接走数据库的降级*/if (JdHotKeyStore.isHotKey(redis_connection_failed)) {JdHotKeyStore.smartSet(redis_connection_failed, {});}// 让后续操作继续判断返回类型是Boolean则返回false其他类型返回nulllog.error(缓存操作失败直接返回 false 或者 null);if (booleanType) {return false;}return null;}
}如果 Redis 故障的话通过 keyredis_connection_failed 就已经记录下来了那么降级操作的话就从本地缓存 caffeine 中取数据如果取不到再查询数据库降级流程如下 这里如果本地缓存中没有数据的话需要查询数据库之后再将数据库中的数据放入本地缓存中这里还是需要加锁的那么我们就加本地锁即可 ReentrantLock