限流系统设计【原创】 限流电子商务
程序员文章站
2022-06-13 19:58:13
...
我司的通关服务平台对接了杭州关区的所有跨境申报业务,近年来,随着跨境电子商务的蓬勃发展,申报的业务单量逐渐增大。尤其是,每年的双十一期间,跨境电商平台都会进行大规模的促销活动,申报的业务单量对我司的跨境通关服务平台造成了很大的压力。据我司的统计数据显示,每年的业务单量都在翻倍上升,预计今年单日交换量在1亿以上。相对于成倍增长的业务单量,我司每年的硬件预算是相对有限,这就对系统稳定运行提出了很大的挑战。因此我们决定研究设计限流子系统,保障系统在高峰期时能够正常稳定运行。
限流子系统主要解决以下问题:
1.分布式限流
对于单机的限流相对比较简单,但是目前我们的业务系统都是具有高度的水平扩展性,业务高峰期我们往往会部署一批节点来分摊系统的压力。比如跨境电子商务通关服务平台,我司在双十一期间,同样的业务系统部署了n个节点,就要对n个节点进行总的申报数量限流。
2.针对不同客户限流
业务系统对接了不同规模的客户,流量控制不能搞一刀切。比如对大电商,我们可以限制1万票/分钟,但是对小电商,我们就可以限制在3千票/分钟,这样就避免了大电商对小电商流量的侵占,同时也可以避免大家一拥而上,把申报通道瓶颈占满。
3.限流算法
限流算法可以分为几种模型:
1)漏桶模型:将流量总池看作一个桶,如果桶装满(达到限流值),那么就开始拒绝业务。一开始桶是空的,当有一票业务到来,就往桶里加一滴水,桶的底部有个漏洞,以恒定的速率外网漏水,每漏出一滴水就相当于放行一票业务。这个模型的优点是,始终以恒定的速率进行业务处理。缺点是由于速率是恒定的,所以即使后端机器在某时刻可以处理更多的业务,也没法从漏桶获取更多的流量,导致机器闲置浪费。
2)简易模型:将流量总池看作一个桶,如果桶里是满的,那么就开始拒绝业务。每来一个业务,就从桶里加一滴水,如果桶可以装的下,就放行一票业务,如果桶装不下,那么拒绝业务。每个时间单元换一个空桶。这个模型的优点是:当流量不均时,后台可以弹性处理业务。缺点是:这个模型有一定的局限性,并不是每时每刻都能保证前后一分钟内流量均衡,最极端情况下有可能出现一分钟有两倍限流值的数据量通过。
3)令牌桶模型:将流量总池看作一个桶,如果桶里是空的,那么就开始拒绝业务。系统每分钟往桶里发放固定数目的令牌,每来一个业务,就从桶里取一块令牌,如果取到令牌就可以放行一票业务,如果桶是空的,那么取不到令牌,就拒绝当前的业务。这个模型的优点是:当流量不均时,后台可以弹性处理业务。
4.性能
限流主要针对的都是大流量,高并发的系统,这些系统往往对性能要求比较高。
5.可靠性
限流功能主要是用来保障业务的可用性的,如果限流功能出现故障,那么将会直接影响业务的可用性。因此限流功能必须就有高度的可靠性,以保证业务的正常运行。
解决方案
应用架构涉及公司的内部系统,这里就不方便贴出来,只贴简单的技术架构:
说明:
1)为了提升系统运行性能,系统采用ehcache+redis的二级缓存技术。
2)为了提升系统运行性能,日志的采集,监控和分析都采用异步技术进行处理。
3)为了提升可靠性,系统采用了集群部署,并采用zookeeper来管理集群的配置。
关键设计
具体设计因为涉及公司的系统也不讲了,只谈几个关键点。
1. 限流包含单机限流和集群限流,单机限流可以采用google的ratelimit组件,集群限流那就得靠redis了。
单机限流
集群限流
2.限流子系统全依赖于缓存,刷新缓存使用管理子系统。刷新本地ehcache缓存,还需要借助zookeeper注册中心
二级缓存的架构
刷新本地缓存
限流子系统主要解决以下问题:
1.分布式限流
对于单机的限流相对比较简单,但是目前我们的业务系统都是具有高度的水平扩展性,业务高峰期我们往往会部署一批节点来分摊系统的压力。比如跨境电子商务通关服务平台,我司在双十一期间,同样的业务系统部署了n个节点,就要对n个节点进行总的申报数量限流。
2.针对不同客户限流
业务系统对接了不同规模的客户,流量控制不能搞一刀切。比如对大电商,我们可以限制1万票/分钟,但是对小电商,我们就可以限制在3千票/分钟,这样就避免了大电商对小电商流量的侵占,同时也可以避免大家一拥而上,把申报通道瓶颈占满。
3.限流算法
限流算法可以分为几种模型:
1)漏桶模型:将流量总池看作一个桶,如果桶装满(达到限流值),那么就开始拒绝业务。一开始桶是空的,当有一票业务到来,就往桶里加一滴水,桶的底部有个漏洞,以恒定的速率外网漏水,每漏出一滴水就相当于放行一票业务。这个模型的优点是,始终以恒定的速率进行业务处理。缺点是由于速率是恒定的,所以即使后端机器在某时刻可以处理更多的业务,也没法从漏桶获取更多的流量,导致机器闲置浪费。
2)简易模型:将流量总池看作一个桶,如果桶里是满的,那么就开始拒绝业务。每来一个业务,就从桶里加一滴水,如果桶可以装的下,就放行一票业务,如果桶装不下,那么拒绝业务。每个时间单元换一个空桶。这个模型的优点是:当流量不均时,后台可以弹性处理业务。缺点是:这个模型有一定的局限性,并不是每时每刻都能保证前后一分钟内流量均衡,最极端情况下有可能出现一分钟有两倍限流值的数据量通过。
3)令牌桶模型:将流量总池看作一个桶,如果桶里是空的,那么就开始拒绝业务。系统每分钟往桶里发放固定数目的令牌,每来一个业务,就从桶里取一块令牌,如果取到令牌就可以放行一票业务,如果桶是空的,那么取不到令牌,就拒绝当前的业务。这个模型的优点是:当流量不均时,后台可以弹性处理业务。
4.性能
限流主要针对的都是大流量,高并发的系统,这些系统往往对性能要求比较高。
5.可靠性
限流功能主要是用来保障业务的可用性的,如果限流功能出现故障,那么将会直接影响业务的可用性。因此限流功能必须就有高度的可靠性,以保证业务的正常运行。
解决方案
应用架构涉及公司的内部系统,这里就不方便贴出来,只贴简单的技术架构:
说明:
1)为了提升系统运行性能,系统采用ehcache+redis的二级缓存技术。
2)为了提升系统运行性能,日志的采集,监控和分析都采用异步技术进行处理。
3)为了提升可靠性,系统采用了集群部署,并采用zookeeper来管理集群的配置。
关键设计
具体设计因为涉及公司的系统也不讲了,只谈几个关键点。
1. 限流包含单机限流和集群限流,单机限流可以采用google的ratelimit组件,集群限流那就得靠redis了。
单机限流
//尝试换取令牌,如果获取不到,拒绝业务 if(!rateLimiter.tryAcquire()){ logger.warn(this.getClass().getName() + " preHandle failure"); return false; } //获取并减少令牌 rateLimiter.acquire(); return true;
集群限流
//针对每个应用调用每个业务接口进行集群限流 long bizCallTimes=cache.hdecr(key, appId+GtwConstants.CACHE_DELIMITER+bizCode); int temp=0; //把多减的补回去 if(bizCallTimes<0){ temp=cache.hincr(key, appId+GtwConstants.CACHE_DELIMITER+bizCode); } return bizCallTimes>=0 || temp>0;
2.限流子系统全依赖于缓存,刷新缓存使用管理子系统。刷新本地ehcache缓存,还需要借助zookeeper注册中心
二级缓存的架构
刷新本地缓存
上一篇: 喷墨打印机打印头堵塞解决有妙法