方案实现
理解限流的常见算法后,就可以进行方案实现了,需要考虑以下4个问题。
使用令牌桶还是漏桶模式
刚刚提到令牌桶算法与漏桶算法都可以满足需求,但是做限流时,项目组希望这个算法不仅可以用于秒杀功能,还可以用于其他限流场景。
而使用漏桶算法存在一个缺陷:比如服务器空闲时,理论上服务器可以直接处理一次洪峰,但是漏桶的机制是请求的处理速度恒定,因此,前期服务器资源只能根据恒定的漏水速度逐步处理请求,无法用于其他限流场景。
如果使用令牌桶算法就不存在这个问题了,因为可以把令牌桶一下子装满。因此,针对这个项目,最终使用的是令牌桶。
在Nginx中实现限流还是在网关层中实现限流
在上述业务场景中,最终决定在网关层实现限流,原因有两点。
1)Nginx中有一个限流插件,它可以对单个用户的请求数做限制,不过它基于漏桶算法,而前面提过,这里希望使用令牌桶算法。
2)当时希望可以动态调整限流的相关配置,就是有一个界面,可以直接管理Nginx的配置。一般这种做法是通过Nginx+Lua实现的,但是因为团队对Lua不熟悉,所以配置人员无法直接操作Nginx中的数据。而团队对Java是很熟悉的。
基于以上两个原因,项目组最终选择在Java的网关层做限流。
使用分布式限流还是统一限流
网关层也是有负载均衡的,多个网关服务器节点可以共享一个令牌桶(统一限流),也可以每个节点有自己的令牌桶(分布式限流)。
如果使用分布式限流的方式,就需要提前计算服务器的数量,然后把100的TPS平分到各个服务器上进行一层换算。
如果使用统一限流的方式,可以把令牌桶的数据存放在Redis中,即每次请求都需要访问Redis,因秒杀开始时下单的请求数往往很大,Redis未必能承受住如此大的QPS。
所以统一限流有一个风险,就是一旦Redis崩溃,限流就会失效,那后台的服务器就会被拖垮。
如果是分布式限流,假设有些节点失效了,那么其他节点还是可以正常工作的,这样导致的问题有两个。
1)部分网关层的负载增加。不管是统一限流还是分布式限流其实都有这个风险,因为在统一限流中网关服务器也可能崩溃。
2)后台处理100个请求的时间拉长。比如有10个网关,每个网关每秒通过10个请求,这样1秒内就有100个请求到后台服务器。假设其中5台失效,那么每秒只能通过50个请求,2秒才能放行100个请求。不过这对当前的业务来说影响不大。
通过对以上问题的衡量,项目组最终决定使用分布式限流方式。
使用哪个开源技术
项目组最终使用开源库Google-Guava中RateLimiter的相关类来实现限流,它是基于令牌桶算法的实现库。这个库在限流场景中还是比较常用的。
使用Google-Guava时,先定义一个Zuul的过滤器(filter),再使用Guava的RateLimiter对提交订单的API请求进行过滤。在使用RateLimiter的过程中,需要配置以下3项。
1)permitsPerSecond:每秒允许的请求数。
2)warmupPeriod:令牌桶多久满。
3)tryAcquire的超时时间:当令牌桶为空时,可以等待新的令牌多久。
分别配置如下。
1)permitsPerSecond设置为100/10=10,100代表想达到的TPS,10代表网关节点为10台,说明每秒可以产生10个令牌。
2)warmupPeriod设置为100毫秒,代表从开始到令牌桶塞满需要100毫秒,即令牌桶的大小是1,如果有10台网关服务器,那么总令牌桶的大小就是10(前面提到过,为防止抢到物品的都是机器人,需要把令牌桶设置为10)。
3)tryAcquire的超时时间设置为0,即拿不到令牌的请求直接抛弃,无须等待。
限流方案的注意事项
在做限流方案时,项目组也遇到过不少的陷阱,下面会把相关的注意事项罗列一下。
限流返回给客户端的错误代码
为了给用户带来好的体验,用户界面上尽量不要出现错误,因此限流后被抛弃的请求应该返回一个特制的HTTPCODE,供客户端进行特殊处理。
而客户端拿到这个错误代码时,就可以展示专门的信息给用户,比如:很遗憾,商品已经秒光,您可以关注下次的秒杀活动。这是第一次秒杀活动的信息。
针对第二次秒杀活动,项目组又增加了如下提示:您可以在10分钟后过来,有些秒杀成功但是没有在10分钟内付款的用户,他们锁定的商品会被释放出来。
实时监控
在实际工作中,最好对限流日志随时做好记录并实时统计,这样有助于实时监控限流情况,一旦出现意外,可以及时处理。
实时配置
因为限流功能还需要应用到秒杀以外的场景,所以最好在配置中心就可以实现对令牌桶的动态管理+实时设置,这样也方便管理其他的限流场景。
秒杀以外的场景限流配置
在这次秒杀活动中,可以简单换算出需要控制数值为100的TPS,而在平时的限流场景中,TPS或QPS(其他场景可能不使用TPS)需要根据实际的压力测试结果来计算,从而进行限流的正确配置。
本文给大家讲解的内容是基于常见组件的微服务场景实战,限流,方案实现及限流方案的注意事项
- 下篇文章给大家讲解的内容是微服务进阶场景实战:微服务的痛:用实际经历告诉你它有多少陷阱
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持!
如若转载,请注明出处:https://www.hanjifoods.com/21902.html