原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter

栏目: 后端 · 发布时间: 6年前

原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter

Dubbo源码之服务端并发控制——ExecuteLimitFilter

  键走偏锋 发布于 昨天 22:04

字数 734

阅读 27

收藏 1

Dubbo

21天精品区块链课程免费学习,深入实战行家带路,助力开发者轻松玩转区块链! >>> 原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter

上一篇关于 《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实现原理与深入研究》

© 著作权归作者所有

共有人打赏支持

原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter

键走偏锋

粉丝 72

博文 554

码字总数 562600

作品 0

通州

程序员

相关文章 最新文章

Dubbo 实现原理与源码解析系列 —— 精品合集

摘要: 原创出处 http://www.iocoder.cn/Dubbo/good-collection/ 「芋道源码」欢迎转载,保留摘要,谢谢! 1.【芋艿】精尽 Dubbo 原理与源码专栏 2.【老徐】RPC 专栏 3.【肥朝】Dubbo 源码解析...

芋道源码掘金 Java 群217878901

06/23

0

0

原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter
Dubbo 并发调优的几个参数

欢迎加入DUBBO交流群:259566260 消费端调优: 一、connections 这个参数可以在服务提供端发布服务的时候配置,也可以在消费端引用服务的时候配置,但是这个值是只对消费端生效的,所以一般是...

Bieber

2015/03/24

0

0

Dubbo源码之客户端并发控制——ActiveLimitFilter

上篇解释了Dubbo源码中降级及容错处理 Dubbo服务调用——Cluster组件(服务降级,容错) 这篇文章主要是关于Dubbo源码中的限流组件,Dubbo限流除了限流(并发限制)的入口ThreadPool 之外,还有...

键走偏锋

昨天

0

0

使用Dubbo中需要注意的事项

一、前言 Dubbo作为高性能RPC框架,已经进入Apache卵化器项目,虽然官方给出了dubbo使用的用户手册,但是大多是一概而过,使用dubbo时候要尽量了解源码,不然会很容易入坑。 二 、服务消费端...

加多

01/02

0

0

dubbo源码分析系列——dubbo-rpc-api模块源码分析

简化的类图 该图是经过简化后的rpc-api模块的类图,去除了一些非关键的属性和方法定义,也去除了一些非核心的类和接口,只是一个简化了的的示意图,这样大家能够去除干扰看清楚该模块的核心接...

杨武兵

2016/05/29

739

3

没有更多内容

加载失败,请刷新页面

加载更多
OSChina 周日乱弹 —— 小云云生日快乐

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《可一可再》- 陈奕迅 《可一可再》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :本汪又老一岁,哇哈哈...

小小编辑

26分钟前

14

4

原 荐 Dubbo源码之服务端并发控制——ExecuteLimitFilter
list集合常用方法

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

redis 主从及集群搭建

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

Ubuntu安装JDK,搭建java环境

因为需要用java环境,就安装了jdk安装环境:ubuntu 18.04,这方法是根据诸博主安装在16.04来的其实现在安装JDK比较简单:下载压缩包,解压,拷贝解压后的文件夹到要放置的路径即可,然后就...

hc321

今天

5

0

Spring Cloud Ribbon 源码分析(零) 配置参数详解

一.前言 Spring Cloud Ribbon主要用于负载均衡,要想使用好,必须先掌握其配置参数; 二.配置参数 2.1 ribbon.eager-load 对应配置类: RibbonEagerLoadProperties enabled : 是否支持RibbonCli...

JackieRiver

今天

3

0

没有更多内容

加载失败,请刷新页面

加载更多

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Spark

Spark

Bill Chambers、Matei Zaharia / O′Reilly / 2017-10-31 / GBP 39.99

Learn how to use, deploy, and maintain Apache Spark with this comprehensive guide, written by the creators of the open-source cluster-computing framework. With an emphasis on improvements and new feat......一起来看看 《Spark》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具