正文
Dubbo源码之服务端并发控制——ExecuteLimitFilter
原
荐
字数 734
阅读 27
收藏 1
Dubbo
21天精品区块链课程免费学习,深入实战行家带路,助力开发者轻松玩转区块链! >>>
上一篇关于 《Dubbo客户端并发控制——ActiveLimitFilter》 作用,设计原理,及配置方式。
这篇是关于Dubbo服务端Filter组件扩展 ExecuteLimitFilter ,它可以限制服务端的方法级别的并发处理请求数。 当请求数超过限制时,服务端采用的是非阻塞处理,如果超出并发数量,则直接进行失败处理(这里抛RPCException异常),这里与客户端限流ActiveLimitFilter 的wait不同的是,这里采用Semaphore 信号量的方式,并且是抢占式的(NonFairSync) , 不明白的可以看下信号量相关源码。
同分析ActiveLimitFilter一样,首先看它的Activate注解信息 :
@Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY)
这里可以得知它是用于服务端限流控制。
ActiveLimitFilter源码:
/** * ThreadLimitInvokerFilter * * @author william.liangf */ @Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY) public class ExecuteLimitFilter implements Filter { public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { URL url = invoker.getUrl(); String methodName = invocation.getMethodName(); Semaphore executesLimit = null; boolean acquireResult = false; //默认不设置executes时候,其值为0 int max = url.getMethodParameter(methodName, Constants.EXECUTES_KEY, 0); if (max > 0) { //max>0说明设置了executes值 RpcStatus count = RpcStatus.getStatus(url, invocation.getMethodName()); // if (count.getActive() >= max) { /** * http://manzhizhen.iteye.com/blog/2386408 * 通过信号量来做并发控制(即限制能使用的线程数量) * 2017-08-21 yizhenqiang */ executesLimit = count.getSemaphore(max); //可知如果并发处理数量大于设置的值,则直接会抛出异常 if(executesLimit != null && !(acquireResult = executesLimit.tryAcquire())) { throw new RpcException("Failed to invoke method " + invocation.getMethodName() + " in provider " + url + ", cause: The service using threads greater than <dubbo:service executes=/"" + max + "/" /> limited."); } } long begin = System.currentTimeMillis(); boolean isSuccess = true; RpcStatus.beginCount(url, methodName); try { // 进行接下来的功能/业务处理 Result result = invoker.invoke(invocation); return result; } catch (Throwable t) { isSuccess = false; if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new RpcException("unexpected exception when ExecuteLimitFilter", t); } } finally { RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, isSuccess); if(acquireResult) { executesLimit.release(); } } } }
当请求并发数大于最大并发数时,则直接失败处理。
服务提供方进行并发控制配置方式如下:
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" group="dev" version="1.0.0" timeout="3000" executes="10" />
设置com.alibaba.dubbo.demo.DemoService 接口中的所有方法,最多同时处理10个并发请求。
也可以通过如下方式单独对每个方法进行并发控制:
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" group="dev" version="1.0.0" timeout="3000" > <dubbo:method name="sayHello" executes="10"/> </dubbo:service>
这里我们采用Semaphore来进行服务端请求的并发控制, 而不是采用 sync 同步代码块 , wait notify 方式的目的是什么呢?
这里Semaphore 代替 sync 实际上是 cas 代替 锁 + wait notify , 虽然Semaphore中底层采用的是单线程CAS , 等待线程LockSupport.park(this); 防止所有线程同时获取令牌的CPU资源消耗。 源码参考之前写的一篇 AQS源码介绍:
《java并发编程之:ReentrantLock实现原理与深入研究》
© 著作权归作者所有
共有人打赏支持
粉丝 72
博文 554
码字总数 562600
作品 0
通州
程序员
相关文章 最新文章
摘要: 原创出处 http://www.iocoder.cn/Dubbo/good-collection/ 「芋道源码」欢迎转载,保留摘要,谢谢! 1.【芋艿】精尽 Dubbo 原理与源码专栏 2.【老徐】RPC 专栏 3.【肥朝】Dubbo 源码解析...
芋道源码掘金Java群217878901
06/23
0
0
欢迎加入DUBBO交流群:259566260 消费端调优: 一、connections 这个参数可以在服务提供端发布服务的时候配置,也可以在消费端引用服务的时候配置,但是这个值是只对消费端生效的,所以一般是...
Bieber
2015/03/24
0
0
上篇解释了Dubbo源码中降级及容错处理 Dubbo服务调用——Cluster组件(服务降级,容错) 这篇文章主要是关于Dubbo源码中的限流组件,Dubbo限流除了限流(并发限制)的入口ThreadPool 之外,还有...
键走偏锋
昨天
0
0
一、前言 Dubbo作为高性能RPC框架,已经进入Apache卵化器项目,虽然官方给出了dubbo使用的用户手册,但是大多是一概而过,使用dubbo时候要尽量了解源码,不然会很容易入坑。 二 、服务消费端...
加多
01/02
0
0
简化的类图 该图是经过简化后的rpc-api模块的类图,去除了一些非关键的属性和方法定义,也去除了一些非核心的类和接口,只是一个简化了的的示意图,这样大家能够去除干扰看清楚该模块的核心接...
杨武兵
2016/05/29
739
3
没有更多内容
加载失败,请刷新页面
加载更多Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《可一可再》- 陈奕迅 《可一可再》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :本汪又老一岁,哇哈哈...
小小编辑
26分钟前
14
4
package package1;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class Demo3 {public static void main(String[] args) {List<Strin......
熊二的爸爸是谁
今天
3
0
php安装redis模块 下载安装 [root[@abc](https://my.oschina.net/aaaaaa) src]# wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip[root[@abc]......
ln97
今天
3
0
因为需要用java环境,就安装了jdk安装环境:ubuntu 18.04,这方法是根据诸博主安装在16.04来的其实现在安装JDK比较简单:下载压缩包,解压,拷贝解压后的文件夹到要放置的路径即可,然后就...
hc321
今天
5
0
一.前言 Spring Cloud Ribbon主要用于负载均衡,要想使用好,必须先掌握其配置参数; 二.配置参数 2.1 ribbon.eager-load 对应配置类: RibbonEagerLoadProperties enabled : 是否支持RibbonCli...
JackieRiver
今天
3
0
没有更多内容
加载失败,请刷新页面
加载更多