我们知道,在Dubbo中可以给Provider配置线程池大小来控制系统提供服务的最大并行度,默认是200个,如果我们想配置成500,可以如下配置:
<dubbo:provider token="true" threads="500"/>
当我们想限制某个dubbo服务使用的最大线程数量时,dubbo提供了executes这一属性来提供这个功能,比如我们想限制某个接口最大能同时使用线程池中的100个线程,我们可以如下配置:
<dubbo:service interface="com.manzhizhen.service.MyLoverService" executes="100" />
我们看下dubbo内部executes是如何实现的,这就得移步到ExecuteLimitFilter,我们直接看下它的实现:
@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();
int max = url.getMethodParameter(methodName, Constants.EXECUTES_KEY, 0);
// 如果该接口/方法设置了executes并且值大于0
if (max > 0) {
// 取出该接口/方法对应的计数器
RpcStatus count = RpcStatus.getStatus(url, invocation.getMethodName());
// 如果当前使用的线程数量已经大于等于设置的阈值,那么直接抛出异常
if (count.getActive() >= max) {
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 isException = false;
// 计数器+1
RpcStatus.beginCount(url, methodName);
try {
Result result = invoker.invoke(invocation);
return result;
} catch (Throwable t) {
isException = true;
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new RpcException("unexpected exception when ExecuteLimitFilter", t);
}
} finally {
// 在finally中进行计数器-1
RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, isException);
}
}
}
看上面的代码,可以得知基本步骤就是(黄底的部分代码):计数器当前值和阈值比较 > 计数器+1 > 计数器-1。这种方式在高并发时会出现静态条件问题的,比如当前该接口已经使用了99个线程,这是时候有两个请求同时到达都发现count.getActive()是小于max的,于是该接口使用的线程数就有可能达到了101个。
那么,我们能不能把RpcStatus.beginCount(url, methodName);放到count.getActive() >= max的前面去执行?仔细想想后也不行,这样做的话有可能在高并发时请求被count.getActive() >= max卡死,因为大量请求将计数器+1(+1的速度远大于原有请求执行完将计数器-1的速度),导致一段时间内计数器一直大于阈值但实际上该接口使用的线程数却是0。
于是,为了将比较和+1做成原子的,我们想到了Semaphore,信号量Semaphore维护了一组许可,用来管理有限的资源,比如这里的线程数。使用Semaphore的有两点需要注意的地方,第一个就是说如果使用不当会导致Semaphore中的许可数多于最初设置的值,或者变为负数,也就是说,Semaphore并没有对非正常使用作出任何保护措施。还有一点是Semaphore没有方法能直接修改许可数量,但我们可以通过间接方法(比如多release几次以增加许可数量),但毕竟不优雅。
<!--StartFragment--> <!--EndFragment-->
Semaphore可以解决上述问题,但当需要修改线程数时,我们应该新建一个Semaphore对象,当采用这种替换Semaphore对象来应对许可数的变化时,一定要确保在仍和情况下acquire和release操作应该在一个Semaphore对象上。这也是我们在设计那些控制并发的小工具时需要注意的地方。
相关推荐
dubbo示例代码dubbo-sample
该文档分析了 Dubbo 框架中 RPC 调用的整个流程,并基于源代码按照执行 时序进行说明,源码版本为2.5.4开发版。 涉及的关键点包括:Invocation、Invoker、Directory、路由、负载均衡、集群容错、过滤器以及监控模块...
Dubbo的源代码打包,2.5.4开发发布版,及与Maven构建,本人亲测,可以编译通过。
Dubbo的源代码打包,2.8.4开发发布版,及与Maven构建,本人亲测,可以编译通过。
dubbo分布式服务框架,方便大家对分布式服务的学习,方便对dubbo的扩展
如果使用dubbo遇到错误:com.alibaba.dubbo.remoting.RemotingException: Fail to decode request due to: RpcInvocation 请下载这个jar,替换掉你项目中的那个jar,应该可以解决。
apache dubbo官网最简单的小例子,只是按照说明弄了下。
此框架为Spring4.1.6+mybatis3.2.8+dubbo2.5.3的框架源码以及依赖的包
dubbodemo-facede : 定义接口,这个项目是要打成jar包分别被dubbodemo-service和dubbodemo-web引用的 dubbodemo-service : 只做逻辑实现,也就是dubbo中的生产者 dubbodemo-web : 负责页面跳转及渲染,也就是dubbo中的...
SSM+dubbo项目源代码
gitbooks对中国人体验不友好,如下地址报404的可以下载此资源。...https://dubbo.gitbooks.io/dubbo-user-book/ https://dubbo.gitbooks.io/dubbo-admin-book/ https://dubbo.gitbooks.io/dubbo-dev-book/
dubbo教程代码demo
本人实际测试过,这两个包可用。 环境描述:centos6/64位,JDK1.8,tomcat8 dubbo-admin安装要点: 1.清空tomcat/webapps/ROOT目录 2.将包解压到tomcat/webapps/ROOT下 3.修改tomcat/webapps/ROOT/WEB-INF/dubbo....
targetNamespace="http://code.alibabatech.com/schema/dubbo"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/> <xsd:import namespace="http://www.springframework.org/schema/beans"/> ...
从源代码构建Dubbo
赠送源代码:dubbo-2.5.8-sources.jar; 赠送Maven依赖信息文件:dubbo-2.5.8.pom; 包含翻译后的API文档:dubbo-2.5.8-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.alibaba:dubbo:2.5.8; 标签:...
本项目只适合dubbo入门学习者,高手请不要浪费金钱; 本项目技术栈 springboot, dubbo ,无 zookeeper 本项目旨在提供最单纯的 dubbo 服务提供者 和消费者的点对点直连,而摒弃任何多余技术对dubbo直连的理解
dubbo入门完整实例,从发布到调用,代码完全实现。
阿里巴巴dubbo2.5.4源代码,内部包含各种demo! 包含dubbo-admin等模块
赠送源代码:dubbo-2.6.1-sources.jar; 赠送Maven依赖信息文件:dubbo-2.6.1.pom; 包含翻译后的API文档:dubbo-2.6.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.alibaba:dubbo:2.6.1; 标签:alibaba、...