• 架构设计之服务限流


    限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等。

    v服务限流概念

    在介绍限流概念之前,我们先来聊聊身边有哪些限流,如果有在帝都的码农估计对限流是最深有感触的,帝都但凡开个XXX会议,各大地铁站都会限流。

    每年的双11都是剁手族的天堂,11月11号0点0几秒的时候,下面这些场景或许你曾经遇到过。

    架构设计之服务限流

    架构设计之服务限流

    当然,这几年双11各大电商对并发的支持做的越来越好,这里只是借鉴双11刚推出之际,常常需要应对的一些问题。

    通过这两个场景,基本上服务限流的作用也就明白:

    「服务限流」其实是指当系统资源不够,不足以应对大量请求,即系统资源与访问量出现矛盾的时候,我们为了保证有限的资源能够正常服务,因此对系统按照预设的规则进行流量限制或功能限制的一种方法。

    v为何要服务限流

    再举一个我们生活中的例子:一些热门的旅游景点,往往会对每日的旅游参观人数有严格的限制,比如北京的故宫、欢乐谷等,每天只会卖出固定数目的门票,如果你去的晚了,可能当天的票就已经卖完了,当天就无法进去游玩了,即使你进去了,排队也能排到你怀疑人生。

    为什么旅游景点要做这样的限制呢?多卖一些门票多赚一些钱岂不是更好?

    其实对于旅游景点而言,她们也很无奈,因为景点的服务资源有限嘛,每日能服务的人数是有限的,一旦放开限制了,景点的工作人员就会不够用,卫生情况也得不到保障,安全也有隐患,超密集的人群也会严重的影响游客的体验。但由于景区名气大,来游玩的旅客络绎不绝,远超出了景区的承载能力,因此景区只好做出限制每日人员流量的举措。

    同理,在IT软件行业中,系统服务也是这样的。

    如果你的系统理论是时间单位内可服务100W用户,但是今天却突然来了300W用户,由于用户流量的随机性,如果不加以限流,很有可能这300W用户一下子就压垮了系统,导致所有人都得不到服务。

    因此为了保证系统至少还能为100W用户提供正常服务,我们需要对系统进行限流设计。

    有的人可能会想,既然会有300W用户来访问,那为啥系统不干脆设计成能足以支撑这么大量用户的集群呢?

    这是个好问题。如果系统是长期有300W的用户来访问,肯定是要做上述升级的,但是常常面临的情况是,系统的日常访问量就是100W,只不过偶尔有一些不可预知的特定原因导致的短时间的流量激增,这个时候,公司往往出于节约成本的考虑,不会为了一个不常见的尖峰来把我们的系统扩容到最大的尺寸。

    v如何服务限流

    对系统服务进行限流,一般有如下几个模式:

    1. 熔断:

    这个模式是需要系统在设计之初,就要把熔断措施考虑进去。当系统出现问题时,如果短时间内无法修复,系统要自动做出判断,开启熔断开关,拒绝流量访问,避免大流量对后端的过载请求。系统也应该能够动态监测后端程序的修复情况,当程序已恢复稳定时,可以关闭熔断开关,恢复正常服务。

    2. 服务降级:

    将系统的所有功能服务进行一个分级,当系统出现问题,需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,这样可以释放出更多的资源供给核心功能的去用。

    例如在电商平台中,如果突发流量激增,可临时将商品评论、积分等非核心功能进行降级,停止这些服务,释放出机器和CPU等资源来保障用户正常下单,而这些降级的功能服务可以等整个系统恢复正常后,再来启动,进行补单/补偿处理。除了功能降级以外,还可以采用不直接操作数据库,而全部读缓存、写缓存的方式作为临时降级方案。

    3. 延迟处理:

    这个模式需要在系统的前端设置一个流量缓冲池,将所有的请求全部缓冲进这个池子,不立即处理。然后后端真正的业务处理程序从这个池子中取出请求依次处理,常见的可以用队列模式来实现。这就相当于用异步的方式去减少了后端的处理压力,但是当流量较大时,后端的处理能力有限,缓冲池里的请求可能处理不及时,会有一定程度延迟。

    4. 特权处理:

    这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。

    那在实际项目中,对访问流量的限制,可采用如下几种技术方法:

    ♛ 熔断技术

    熔断的技术可以重点参考Netflix的开源组件hystrix的做法,主要有三个模块:熔断请求判断算法、熔断恢复机制、熔断报警。

    服务限流
    来自hystrix github wiki         查看大图

    ♛ 计数器方法

    系统维护一个计数器,来一个请求就加1,请求处理完成就减1,当计数器大于指定的阈值,就拒绝新的请求。

    基于这个简单的方法,可以再延伸出一些高级功能,比如阈值可以不是固定值,是动态调整的。另外,还可以有多组计数器分别管理不同的服务,以保证互不影响等。

    ♛ 队列方法

    就是基于FIFO队列,所有请求都进入队列,后端程序从队列中取出待处理的请求依次处理。

    基于队列的方法,也可以延伸出更多的玩法来,比如可以设置多个队列以配置不同的优先级。

    ♛ 令牌桶方法

    首先还是要基于一个队列,请求放到队列里面。但除了队列以外,还要设置一个令牌桶,另外有一个脚本以持续恒定的速度往令牌桶里面放令牌,后端处理程序每处理一个请求就必须从桶里拿出一个令牌,如果令牌拿完了,那就不能处理请求了。我们可以控制脚本放令牌的速度来达到控制后端处理的速度,以实现动态流控。

    v注意事项

    我们在做服务限流的时候,还是有一些原则和事项需要注意的:

    • 实时监控:系统必须要做好全链路的实时监控,才能保证限流的及时检测和处理。
    • 手动开关:除系统自动限流以外,还需要有能手动控制的开关,以保证随时都可以人工介入。
    • 限流的性能:限流的功能理论上是会在一定程度影响到业务正常性能的,因此需要做到限流的性能优化和控制。

    v博客总结

    系统故障常常都是不可预测且难以避免的,因此作为系统设计师的我们,必须要提前预设各种措施,以应对随时可能的系统风险。


    作  者:请叫我头头哥
    出  处:http://www.cnblogs.com/toutou/
    关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

  • 相关阅读:
    Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task(枚举/最大连续子序列)
    Educational Codeforces Round 88 (Rated for Div. 2) A. Berland Poker(数学)
    Educational Codeforces Round 88 (Rated for Div. 2) E. Modular Stability(数论)
    Educational Codeforces Round 88 (Rated for Div. 2) C. Mixing Water(数学/二分)
    Codeforces Round #644 (Div. 3)
    Educational Codeforces Round 76 (Rated for Div. 2)
    Educational Codeforces Round 77 (Rated for Div. 2)
    Educational Codeforces Round 87 (Rated for Div. 2)
    AtCoder Beginner Contest 168
    Codeforces Round #643 (Div. 2)
  • 原文地址:https://www.cnblogs.com/toutou/p/9593569.html
Copyright © 2020-2023  润新知