在前面的一篇中分析了Dubbo是如何降级的,除了降级,有时限流也是一种很有效的解决高并发的性能问题,那在本篇中开始分析Dubbo是如何限流的。我们知道限流主要是通过控制连接数来实现的,防止某一片段内请求处理过大,导致重要服务的失效。
服务端连接控制
限制当前提供者在使用dubbo协议最多接受10个消费者链接
或者
并发控制
限制 comfooBarService 的每个方法,服务端并发执行(或占用线程池线程数)不能超过10个:
限制 comfooBarService 的 sayHello 方法,服务器并发执行(或占用线程池线程数)不能超过10个。
actives限流
该限流方式与前两种不同,其可以设置在提供端,也可以设置在消费者端。可以设置为接口级别,也可以设置为方法级别。
根据消费者与提供者建立的连接类型,其意义也不同。
长连接 : 表示当前的长连接最多可以处理的请求个数。与长连接的数量没有问题。
短连接 :表示当前服务可以同时处理的短连接数量。
类级别
方法级别
connections限流
可以设置在提供端,也可以设置在消费者端。限定连接的个数。对于短连接,和actives相同。但对于长连接,表示长连接的个数。
一般情况下,会使connections与actives联用,让connections限制长连接的个数,让actives限制长连接中可以处理的请求个数。
限制客户端服务使用连接不能超过10个
或
如果 <dubbo:service> 和 <dubbo:reference> 都配置了connections, <dubbo:reference> 优先。
延迟连接
延迟连接仅可以设置在消费者端,并且不能设置为方法级别。仅作用于Dubbo服务暴露协议。将长连接的建立推迟到消费者真正调用提供者时。 可以减少长连接的数量。
我们已经讲解了如何设置控制链接数的,那么它们底层是如何实现的呢?
实际上上面的逻辑都是一个个Filter,所有的Filter会连接成一个过滤器链,每次请求都会经过整个链路中的每一个Filter。那它是在什么时候构造成一个过滤器链的呢。
在服务暴露的时候会调用 buildInvokerChain , 将真正执行的 invoker 放到过滤链的尾部,再执行 protocolexpert(buildInvokerChain(invoker, )) 方法来进行服务暴露。
在服务引用的时候会调用 protocolrefer() 方法先生成 Invoker ,再调用 buildInvokerChain(protocolrefer(type, url), ) 来生成消费类型的调用链。
ExecuteLimitFilter
它用于限制每个服务中每个方法的最大并发数,有接口级别和方法级别的配置方式。
其基本原理:在框架中使用一个ConcurrentMap缓存了并发数的计数器,为每个请求URL生成一个IdentityString,并以此为key;再将每个IdentityString生成一个RpcStatus对象,将此作为value。RpcStatus对象用于记录对应的并发数。在调用开始之前,会通过URL获得RpcStatus对象,把对象中的并发数计数器原子+1,在finally中再将原子减1。只要在计数器+1的时候,发现当前计数器比设置的并发数大时,就会抛出异常。
TpsLimitFilter
TpsLimitFilter的限流是基于令牌的,即一段时间内只分配N个令牌,每次请求都会消耗一个令牌,耗完为止,后面再来的请求都会被拒绝。
具体的逻辑是在 DefaultTPSLimiter#isAllowable ,会用这个方法判断是否触发限流。
在DefaultTPSLimiter内部用一个ConcurrentHashMap缓存每个接口的令牌数,key是interface+group+version,value是一个StatItem对象,它包装了令牌刷新时间间隔、每次发放的令牌数等。首先判断当前时间减去上次发放令牌的时间是否超过了时间间隔,超过了就重新发放令牌,之前剩余的令牌会被直接覆盖掉。然后,通过CAS的方式减去1令牌,减掉后小于0就会触发限流。
ActiveLimitFilter
和服务提供者的 ExecuteLimitFilter 相似,它是消费者端的过滤器,限制的是客户端的并发量。
但是它与 ExecuteLimitFilter 有所不同,它不会直接抛出异常。而是当到达阈值的时候,会先加锁抢占当前接口的RpcStatus对象,然后通过wait方法进行等待,等待是有时间的,因为请求是有 timeout 属性的。然后如果某个Invoker在调用结束后,并发把计数器减-1并触发一个notify,此时会有一个在wait状态的线程被唤醒并继续执行,判断现在是否超时,如果超时则抛出异常。如果当前并发数仍然超出阈值,则继续执行wait方法;如果没有超出阈值在,则跳出循环,CAS+1,并调用invoke方法,调用结束后CAS-1,最后通过notify唤醒另外一个线程。
参考文章:
Dubbo之限流TpsLimitFilter源码分析
Dubbo服务限流
Dubbo源码分析----过滤器之ActiveLimitFilter
1 减少接口调用频率。根据菜鸟驿站的限流规则,短时间内大量调用接口容易触发限流。您可以尝试降低程序运行频率,减小同一时间内的接口调用次数。一旦限流解除,再逐渐提高频率。
2 使用缓存数据。如果您的业务场景允许,可以考虑将部分接口返回的数据进行缓存,减少重复调用相同接口的次数。但需要注意数据的时效性,定期更新缓存。
3 更换接口域名。菜鸟驿站提供多个域名供调用,xn--api-eo8ecainiaocom、apiv2cainiaocom等。您可以尝试切换到其他域名,限流规则在不同域名之间是独立的。
4 轮询多个接口。如果一个接口被限流,可以尝试调用其他未限流的接口。比如在查询物流信息时,可以轮流调用多个物流公司的接口,不依赖某单一接口。一旦限流解除,再集中调用优先接口。
5 联系菜鸟驿站技术支持。如果以上方法均无法解决限流问题,则需要联系菜鸟驿站的技术支持人员,提供限流错误码及相关条件,询问解决方案。菜鸟技术支持人员将会根据您的业务场景提供更加准确可行的解决办法。
菜鸟驿站限流主要是为了保障系统稳定性和业务安全,希望开发者能理解并配合相应措施。如果您遵循菜鸟公布的接口调用规范,限流现象一般会大幅减少。同时,菜鸟技术团队也在持续优化系统,提高接口稳定性。
主要分为三类流量限制:
一、流量限制
就是直接限制网络流量,这种限制通常是最严厉的一种流量限制,10个g的流量大体支持50人在线以内,当月流量超过后,在一个月内网站都不能正常访问了,解决办法是升级空间或加大流量。
二、CPU限制
CPU限制看起来没有限IIS或网络流量,但由于每一个程序运行都需要一定的CPU配额,也是变相的流量限制,通常网页显示在线过多都是由于CPU限额过小引起的!通过刷新或15秒后可以得到暂时的正常运行,通常1%的CPU限额相当于20个IIS连接!这对于论坛空间很重要,论坛的CPU限额一旦过小就会不能正常运行。
三、IIS限制
IIS限制是现在用的最多的,也是被大多用户或主机商认可,是唯一宽松的流量限制,通常20个IIS就相当于1%CPU占用。
网络流控-控制实现
随着网络技术的快速发展,基于网络的应用越来越多、越来越复杂。种类繁多的应用正在吞噬着越来越多的网络资源,网络作为一种新的传媒载体,也正在遭受媒体的冲击。
尤其是网络视频、个人媒体、传统电视等媒体向互联网的渗入是的网络中的流量急剧上升,这使得运营商的运营和管理成本大幅度增长。运营商可以应用限流的方法控制网络流量,但这同时也限制了网络媒体的发展,最终不利于互联网的进一步发展。于是开发一种新的技术来控制网络流量成为一个研究热点。
现阶段互联网上的流量主要由P2P和>
通过对多种网络流量控制系统的比较,然后采用一种最优的系统。将系统部署在网络出口来缓存P2P和>
以上内容参考 百度百科-流量控制
限流是一种流量控制技术,通常用于防止服务器或网站被恶意攻击或过度负载而导致的故障。在电脑脚本中,限流可以通过以下几种方式来实现:1使用队列来缓存请求,并在适当的时候处理这些请求。这样,即使服务器在短时间内收到大量请求,也可以通过缓存请求来降低压力。
2使用令牌桶算法来限制请求的流量。这种算法会在每个时间单位内向桶中放入一定数量的令牌,如果桶中有令牌,则允许请求通过,否则拒绝请求。
3使用限流中间件来处理请求。这种方法可以让你不用在你的脚本中编写限流代码,而是使用现成的中间件来实现。
无论使用哪种方法,都应该在脚本中考虑到限流,以保护服务器或网站免受恶意攻击或过度负载的影响。
简述:
Spring Cloud Zuul RateLimit项目Github地址:
>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)