高并发系统三大利器:缓存、降级(熔断)和限流。
缓存:
很好理解,在高并发系统中,没有缓存,数据库分分钟就被玩跪了。使用缓存不单单能够提升系统访问速度、提高并发访问量,也是保护数据库、保护系统的有效方式。
降级和熔断
两者相似,但是还是有区别的。
降级:针对于整体服务,整体负荷超出整体负载承受能力时,延迟或暂停非重要服务,例如日志收集服务,保证重要服务正常运行。
熔断:针对于单个服务,当某一服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施。直接关闭该服务(比较暴力)或者保证部分请求成功,另一部分直接返回失败(不占用服务资源),eg.如果5秒钟之内连续请求失败次数达到20次,那么触发熔断机制,过滤60%的请求。
限流:
限流可以认为服务降级的一种,限流就是限制系统的访问量已达到保护系统的目的。
常见的限流算法有:计数器、漏桶和令牌桶算法。
计数器:
一个典型的应用场景就是规定在固定的时间内,只允许通过固定数量的请求,如规定在一分钟内只允许处理100个请求。
基本思想:有一个counter。当一个请求到来的时候,首先判断现在是否是处于新的时间段里。如果是在新的时间段了,就可以把counter清0,然后对当前这个请求进行计数加一操作。假如没有处于新的时间段,则判断当前的counter的数量是否超过规定的数量,如100。超过了就丢弃请求,否则对计数器加一,允许该请求通过。
存在问题:精度不够,请求分布不平均。当在时间的临界区的时候,可能会出现问题。例如,规定一分钟处理100个请求,第一秒就有100个请求,也会造成系统压力,后面59秒系统空闲。
漏筒算法:
-
一个固定容量的漏桶,按照常量固定速率流出水滴;
-
如果桶是空的,则不需流出水滴;
-
可以以任意速率流入水滴到漏桶;
-
如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
令牌桶算法:
一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。
- 令牌将按照固定的速率被放入令牌桶中。比如每秒放10个。
- 桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝。
- 当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上。
- 如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。
假如我们现在是国庆放假,故宫要做限流措施,对故宫的游客数量进行控制。因此工作人员准备半个小时,派出100张票,也就是每半个小时生成100张票。假如游人很多,那么每次100张票都能在半小时内用完,其他游客没票了,只能在外面等着,不让进。那假如游人很少,半个小时100张没用完,那么就会累积在那儿,半个小时后又新生成100张。因此售票处的票会越来越累积起来。假如突然来了一个大型旅行团,游客数量很多,那么此时由于前面还累积了很多票,因此即使这个旅行团超过100,也能使他们每个人都有票。
漏桶和令牌桶算法的区别
“漏桶算法”能够强行限制数据的传输速率,而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,所以它适合于具有突发特性的流量。 (在突发传输时,漏桶算法即使有很多空闲资源也会按照一定速率传输,令牌桶算法则可以在足够空间的前提下,一次性进行传输)