在高并发业务系统开发的过程中,我们经常提到QPS的概念。QPS顾名思义就是每秒能处理的请求数,超过这个数值,系统的响应时间就会增大,甚至会导致系统崩溃宕机,所以,对于QPS的限制,一个健壮的系统是必须要做的。
1、QPS如何计算
首先,我们要知道QPS的一个计算方法,有助于我们对于系统的QPS有个大概的估计。根据二八原则,80%的请求都发生在20%的时间之内。假设我们一天有1亿的请求次数:
qps = 100000000*0.8/24*3600*0.2 = 4629所以,如果只有一台机器的话,那qps=4629左右。单机最大qps我们可以通过压测来评估。如果我们定义接口在1s之内能响应属于正常情况,那压测的时候,我们逐渐增大模拟的qps,当接口平均响应时间大于1s,那此时的qps就是系统能接受的最大qps。
2、常见的限流算法
常见的限流算法主要有漏桶和令牌桶两种:
漏桶:一个装满水的桶,每秒向外漏一滴, 如何当前请求能接到,那就可以正常请求,否则,就只能等待下一滴水。
令牌桶: 令牌桶是指按照固定周期向桶中添加令牌,令牌的数目可以实际QPS进行调整,请求时需要从桶中获取令牌,如果没有令牌,可以选择等待,或者放弃。
两种方法看起来很像,但还是有区别的。漏桶的速率是固定的,而令牌桶则是只要桶中有令牌,请求就可以拿。所以这在一定程度允许并发。假设桶中有10个令牌,同时有10个请求发起,那这10个请求都可以拿到令牌。
令牌桶是实际应用比较广泛的限流算法。很多限流算法都是基于令牌桶的思想实现的。
3、Golang中如何限制QPS
限制QPS我们采用限流算法。Ratelimit是Golang下的一个限流算法的实现。
Ratelimit
Ratelimit几种填充令牌的方法。
Ratelimit提供了几种填充令牌的方式。
NewBucket默认的填充方式,按照固定时间放一个令牌。桶的容量是固定的。
NewBucketWithRate按照频率填充。例如capacity是100,而rate是0.1,那么每秒会填充10个令牌。
NewBucketWithQuantum按照固定时间放N个令牌,N可以自定义。
4、实际应用
设置桶
我们采用NewBucketWithQuantum填充方式。首先计算系统能承受的qps,然后每秒填充qps大小个令牌,桶的容量也是qos大小。
从桶获取令牌
接收到请求以后,从桶中获取令牌,如果可以获取到令牌,业务正常执行。否则,本次请求抛弃。
最后:限流对于系统的健壮性很重要,高并发系统中必须要有限流,限流可以保证系统在流量高峰期正常运行。
领取专属 10元无门槛券
私享最新 技术干货