zoukankan      html  css  js  c++  java
  • 关于服务限速的那些事

    前言

    前天,我们分享了guava工具包中的一个限速组件——RateLimiter,由于当时说后续要继续分享微服务限速的内容,所以我又专门梳理微服务限速相关的解决方案,今天抽时间来做一个梳理。

    限流算法

    关于限速这块的解决方案,从部署方面来说,主要分为两大块:

    一块是单体应用限速,我们之前说的RateLimiterSemaphore都属于此类;

    另一块是针对分布式服务的限流(集群部署),这一块的解决方案也可应用于单体服务,其中绝大多数都是基于Redis这样的缓存实现的,另外还有基于Nginx实现的。

    限流算法大致分为三类:计数器、漏桶和令牌桶。

    计数器算法

    计数器属于比较常用的限流算法,计数器算法的原理是通过限制在一段时间内接口被调用的次数,来控制接口流量。比如钉钉消息接口的限流,一个第三方企业一分钟只能发送3000条消息(具体数量我记不清楚),超过3000条的部分只能等一分钟之后发送,这样的场景就可以通过计数器算法来实现。

    实现原理

    实现方式也很简单,可以通过缓存来实现,我的思路是:在接口内部最开始的地方,设置调用方的计数器(key为调用方唯一的身份信息),第一次调用时将其值设置为1并放进缓存中,同时缓存设置过期时间,有效期内每次调用计数器+1,时间过期,缓存会自动删除。可以把相关逻辑封装成自定义注解,搞成通用组件,这样只需要在需要限速的接口上加上对应的的注解即可,明天我们可以来实现下。

    优缺点

    这种算法优点是算法简单,易于实现,但是缺点也很明显:因为是时间段控制,所以流量本身并不是平衡的,很有可能一个时间段流量特别搞,而其他时间点又没有请求,这样还是会存在宕机的可能性。比如你限制接口一分钟只能调用1000次,那很有可能在第一秒的时候直接被调用1000次,而之后没有请求,这样你的服务很有可能在第一秒的时候就挂掉。

    漏桶算法

    关于漏桶算法,我们先看一张图:

    上面这张图就可以很形象地说明漏桶算法的原理:首先我们需要定义一个容量固定的漏桶,因为外部请求数量是不确定的,所以我们要通过漏桶的容量来控制请求数量。同时要确定漏桶释放请求的速率(出口),我们通过出口的速率,控制接口服务被调用的频速。当漏桶中的请求数达到上限时,所有申请加入漏桶的请求都会被丢弃掉。

    这样的应用场景在日常生活中也有很多,比如节假日地铁限流、景点限流等,都是这样的操作。

    和前面的计数器限速,这里的限速模式就更合理,同时也更复杂,关于它的具体实现,我们最近也会有相关实例分享。

    令牌桶算法

    我们先看下令牌算法的原理图:

    在令牌桶算法中,令牌生产算法以恒定速率不断生成新的令牌放进令牌桶中,当数量达到令牌桶的上线时,生成的新令牌会被丢弃掉。对客户端请求来说,每次请求处理前,先要从令牌桶中获取令牌,如果获取到令牌,则进出接口服务处理相关请求,否则请求被拒绝。

    令牌桶和漏桶算法有点像,但是他们的实现原理是有区别的,首先在漏桶算法中是由漏桶来控制请求速率的,而在令牌桶的算法中,是由令牌生成算法控制请求速率的,令牌桶只是充当了容器。

    令牌桶在日常生活中也有很多的应用,比如陕西历史博物馆每日定量发票参观。另外,在实际限流应用开发中,令牌桶也有着很典型的应用场景,比如guavaRateLimter就采用了令牌桶算法。

    知识扩展

    这里我们再分享一些常见的限流组件,后续我们会进一步剖析这些框架,今天知识简单的罗列,也算是梳理后期内容的更新方向:

    • Sentinel:面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。
    • concurrency-limits:奈飞公司出品的限流解决方案,我也是今天才检索到,它是一款自适应限流神器,后面抽时间学下
    • Hystrix:这也是奈飞公司出品的一款断路器工具,之前我们有分享过Hystrix在服务熔断方面的应用,昨天我又专门重新发了下,感兴趣的小伙伴可以去看下,后面还要再学习下这款组件在资源隔离、服务降级等方面的应用。

    结语

    好了,关于限流解决方案这块我们暂时先说这么多,算法这块网上资源也比较丰富,有兴趣的小伙伴可以检索更详细的内容,后续我们会逐步来分享更详细的demo实践过程,希望能通过整个过程,对服务限流这块有更深入的认知和理解。

  • 相关阅读:
    计划任务
    swap
    fdisk
    raid 搭建
    Http协议中Cookie详细介绍
    linux系统日志以及分析
    搞清楚php-FPM到底是什么?
    Amoeba+Mysql实现数据库读写分离
    Last_SQL_Error: Error 'Can't drop database 'ABC'; database doesn't exist' on query. Default database: 'ABC'. Query: 'drop database ABC'
    MySQL主从失败, 错误Got fatal error 1236解决方法
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/15491790.html
Copyright © 2011-2022 走看看