雪崩处理

常见的过载情况有两种:队列式过载,命令组合式过载。

队列式过载:

执行流间通过fifo的队列进行通信,比如udp套接字的缓冲区,后端同步地从队列中读出请求并处理,若是缓冲区设置过大,请求量一旦超过后端的能力,整个服务就会全面崩盘。

具体缓冲区长度设计:

         前端超时假设是T秒,后端能力是P,每个请求的大小是S,那么我们的缓冲区应小于T*P*S,假设前端超时200ms,后端能力是5000/S,每个请求的大小是300B,那么缓冲应小于:0.2*4000*300=240KB。(注:udp缓存也存放元数据,包大小300B实际占用的可能是500多B,需要根据实际情况计算)

         当然也有其它处理方式:给请求记录时间,或用异步的interface快速丢弃

 

命令组合是过载:

         假设过一个任务需要有N步请求组合起来,而且每一步都是关键步骤。假设是10步,单后端的失败率达到10%时,组合失败就是65%,自动重试和用户重试会加重系统发负载,整个服务就会几乎不可用了。

         处理方法:评估计算整个系统的最大负载,超过负载时在组合的第一步直接拒绝,delay用户重试的机会,可采取类似TCP重传的退让方式。

### 解决缓存雪崩的方法及最佳实践 #### 方法一:设置随机过期时间 为了避免大量缓存同时失效,可以通过为不同键值对设置不同的过期时间来实现。这种做法能够有效减少因同一时间段内多个缓存失效而导致的压力集中现象[^1]。 ```python import random def set_cache_with_random_expiry(redis_client, key, value): base_ttl = 300 # 基础TTL秒数 random_offset = random.randint(0, 60) # 随机偏移量 ttl = base_ttl + random_offset redis_client.setex(key, ttl, value) ``` #### 方法二:引入本地缓存 为了进一步降低 Redis 缓存失效带来的冲击,可以在应用程序中加入一层本地缓存(如 Ehcache 或 Guava Cache),这样即使 Redis 中的数据全部失效,也可以依靠本地缓存暂时支撑业务逻辑运行[^2]。 #### 方法三:使用分布式锁更新缓存 当某个缓存项即将到期时,可以采用加锁机制让唯一线程负责新加载该数据并写回缓存。其余请求则等待此操作完成后再获取最新版本的内容,从而避免多次复查询数据库造成额外负载。 ```java public String getWithLock(String key){ String result = redis.get(key); if (result == null){ synchronized(lockObject){ result = redis.get(key); // Double check after acquiring the lock. if(result == null){ result = db.queryData(); // Fetch from DB as fallback. redis.setExpiry(key,result,"PT5M"); // Set with TTL again. } } } return result; } ``` #### 方法四:预热缓存 在高并发场景下启动服务前或者流量高峰来临之前主动预先加载可能被访问的资源至内存当中形成热备状态;另外还可以借助定时任务周期性的刷新那些要的高频使用的对象列表以保持其始终处于可用之中[^3]。 #### 方法五:限流与熔断保护措施 利用像Hystrix这样的工具库实施API级别的速率限制以及失败快速响应策略可以帮助抵御突发状况下的性能瓶颈风险。一旦检测到异常高的延迟或者其他指标超标,则立即切换到备用流程直至恢复正常为止。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值