开篇
这是一篇概要文,具体的业务高并发的3大银弹:限流、缓存、降级。之所以把限流排第一位,是我认为缓存和降级属于限流的手段。
限流
流量太大,可以通过如下方式进行处理。
- 缓存过滤:包括静态资源的CDN,服务数据的Redis缓存
- 拒绝服务:只允许部分请求得到响应,其他请求直接拒绝。漏洞筒、令牌桶【二级缓存】
- 异步处理:利用MQ来削峰,虽然实时性减弱,但是维护了服务稳定
- 服务降级:让部分业务不可用,也能减少流量
- 服务熔断:直接返回请求方DEFAULT资源
缓存
常用的算法有:
- FIFO:先进先出,淘汰的总是先进入的
- LRU:淘汰最久未使用的元素
- LFU:淘汰最少使用的元素
缓存的类型:
- 本地缓存,LocalCache,比如在进程中的缓存
- 全局缓存,GlobalCache,比如Redis做的缓存
需要注意的问题是如果二级缓存,那么一致性的问题如何保证:PUB/SUB的通知,Redis/MQ/JGROUPS。
静态数据的缓存:
缓存的问题
- 缓存穿透:
- 定义:查询不存在的值,NULL。
- 办法:缓存NULL
- 缓存雪崩:
- 定义:缓存集体失效时,流量被打倒DB
- 办法:通过抖动相同过期时间进行缓解 OR 异步更新(定时更新)
- 缓存击穿
- 定义:某一个缓存生效,但是该资源为热点资源。
- 办法:异步更新缓存
数据修改后的缓存一致性问题
- 推荐1:普通数据,修改数据后,删除缓存。【有需要的时候(查询时)才去缓存数据】
- 推荐2:热点数据,异步刷新缓存
降级
指某些不重要的服务暂缓处理,让出资源给核心服务。比如双十一高峰时候不允许取消订单、不允许查看历史订单等,都属于降级。
类似的概念:熔断,它是为了解决服务雪崩的手段。通常是在:自身服务对于所请求的它方服务出现异常情况时,为了缓解雪崩不再请求,而是采用自身定义的默认返回值的手段。
二者目的都是为了保证服务的稳定性,但是都造成了功能的减弱。
骐骥一跃,不能十步。驽马十驾,功在不舍。