dubbo线程模型
dubbo的provider有2种线程池:
- IO处理线程池。(直接通过netty等来配置)
- 服务调用线程池。
如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度。
但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则 IO 线程阻塞,将导致不能接收其它请求。
如果用 IO 线程处理事件,又在事件处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。

因此,需要通过不同的派发策略和不同的线程池配置的组合来应对不同的场景:
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
- Dispatcher
all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。
message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
- ThreadPool
fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
cached 缓存线程池,空闲一分钟自动删除,需要时重建。
limited 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
eager 优先创建Worker线程池。在任务数量大于corePoolSize但是小于maximumPoolSize时,优先创建Worker来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列中。阻塞队列充满时抛出RejectedExecutionException。(相比于cached:cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列)
上面是摘自官方的解释,下面进行研究:
producer.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app">
<!-- 关闭QOS:Quality of Service -->
<dubbo:parameter key="qos.enable" value="false" />
<dubbo:parameter key="qos.accept.foreign.ip" value="true" />
<dubbo:parameter key="qos.port" value="2222" />
</dubbo:application> <dubbo:registry address="zookeeper://127.0.0.1:2181"
subscribe="false" dynamic="false" /> <!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/> <!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="dubbo.DubboService" ref="demoService"
timeout="500000" /> <!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="dubbo.DubboServiceImpl" />
</beans>
consumer.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app">
<!-- 关闭QOS:Quality of Service -->
<dubbo:parameter key="qos.enable" value="false" />
</dubbo:application> <!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="dubboService" interface="dubbo.DubboService" />
</beans>
Consumer.java开启20个线程消费服务
package dubbo; import java.util.concurrent.CountDownLatch; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Consumer { private static final Logger LOGGER = LoggerFactory.getLogger(Consumer.class); public static void main(String[] args) throws InterruptedException {
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "consumer.xml" });
context.start();
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() { @Override
public void run() {
DubboService service = (DubboService) context.getBean("dubboService");
LOGGER.info(service.sayHello(" china "));
}
}).start();
} CountDownLatch countDownLatch = new CountDownLatch(1);
countDownLatch.await();
}
}
多次访问之后,消费者线程数量会一直增加,并且消费完成之后线程并不会结束,并且每次访问结束都会增加20个线程。如下:

(1)测试 direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。(多个线程同时请求是一种同步执行的方式,服务端始终只有一条线程处理请求),如下:
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" dispatcher="direct"/>
查看线程信息:

(2)使用固定fixed线程池处理并且大小定为20
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" dispatcher="all"
threadpool="fixed" threads="20" />
多次访问线程数量仍然定在最高的20,不会增加。(这种情况适用于最大并发量是20的请求)
如果同时访问超过20个,会报下面错误:
Exception in thread "Thread-0" com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method sayHello in the service dubbo.DubboService. Tried 3 times of the providers [192.168.0.232:20880] (1/13) from the registry 127.0.0.1:2181 on the consumer 192.168.0.232 using the dubbo version 2.6.6. Last error is: Failed to invoke remote method: sayHello, provider: dubbo://192.168.0.232:20880/dubbo.DubboService?anyhost=true&application=consumer-of-helloworld-app&bean.name=dubbo.DubboService&check=false&dubbo=2.0.2&dynamic=false&generic=false&interface=dubbo.DubboService&methods=sayHello&pid=5132&qos.enable=false®ister.ip=192.168.0.232&remote.timestamp=1554373603443&side=consumer&timeout=500000×tamp=1554374765210, cause: Server side(192.168.0.232,20880) threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-192.168.0.232:20880, Pool Size: 20 (active: 20, core: 20, max: 20, largest: 20), Task: 67 (completed: 47), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://192.168.0.232:20880!
at com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:102)
(3)limited 在同时访问超过线程数的时候多余请求被拒绝
并且在生产者控制台打印如下信息
18:54:22 [com.alibaba.dubbo.common.threadpool.support.AbortPolicyWithReport]-[WARN] [DUBBO] Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-192.168.0.232:20880, Pool Size: 20 (active: 20, core: 0, max: 20, largest: 20), Task: 21 (completed: 1), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://192.168.0.232:20880!, dubbo version: 2.6.6, current host: 192.168.0.232
多余的客户端请求报错同上面一样,
Server side(192.168.0.232,20880) threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-192.168.0.232:20880, Pool Size: 20 (active: 20, core: 0, max: 20, largest: 20), Task: 21 (completed: 1), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://192.168.0.232:20880!
dubbo线程模型的更多相关文章
- 第十章 dubbo线程模型
一 netty的线程模型 在netty中存在两种线程:boss线程和worker线程. 1 boss线程 作用: accept客户端的连接: 将接收到的连接注册到一个worker线程上 个数: 通常情 ...
- dubbo线程模型配置
首先了解一下dubbo线程模型 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,比如只是在内存中记个标识.则直接在IO线程上处理更快,因为减少了线程池调度. 但如果事件处理逻辑较慢,或者需要发 ...
- Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)
文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...
- Dubbo学习笔记8:Dubbo的线程模型与线程池策略
Dubbo默认的底层网络通讯使用的是Netty,服务提供方NettyServer使用两级线程池,其中 EventLoopGroup(boss) 主要用来接受客户端的链接请求,并把接受的请求分发给 Ev ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 线程模型
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 线程模型 事件处理线程说明 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求 ...
- 【原创】Dubbo 2.7.5在线程模型上的优化
这是why技术的第30篇原创文章 这可能是全网第一篇解析Dubbo 2.7.5里程碑版本中的改进点之一:客户端线程模型优化的文章. 先劝退:文本共计8190字,54张图.阅读之前需要对Dubbo相关知 ...
- 彻底搞懂 netty 线程模型
编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...
- 面试官:Netty的线程模型可不只是主从多Reactor这么简单
笔者看来Netty的内核主要包括如下图三个部分: 其各个核心模块主要的职责如下: 内存管理 主要提高高效的内存管理,包含内存分配,内存回收. 网通通道 复制网络通信,例如实现对NIO.OIO等底层JA ...
- 一文弄懂-Netty核心功能及线程模型
目录 一. Netty是什么? 二. Netty 的使用场景 三. Netty通讯示例 1. Netty的maven依赖 2. 服务端代码 3. 客户端代码 四. Netty线程模型 五. Netty ...
随机推荐
- Python脱产8期 Day13 2019/4/28
一 函数的嵌套定义 1在一个函数的内部定义另一个函数. 2.为什么有函数的嵌套定义: # 1)函数fn2想直接使用fn1函数的局部变量,可以讲fn2直接定义到fn1的内部,这样fn2就可以直接访问fn ...
- 性能测试监控平台:InfluxDB+Grafana+Jmeter
前面的博客介绍了InfluxDB.Telegraf.Grafana的安装和使用方法,这篇博客,介绍下如何利用这些开源工具搭建性能测试监控平台... 前言 性能测试工具jmeter自带的监视器对性能测试 ...
- java oop 集合框架
集合主要是用来存放数据的,集合与数组的主要区别在于,集合的大小不受限制,而数组的大小受限制,在使用集合增加数据时又常常与泛型联系起来,所以集合和泛型在实际开发过程中总会结合在一起 数组致命的缺点是数组 ...
- 开发神器之PHPstorm配置及使用
之前文章对于PHPstorm有了简单的介绍,作为一名合格的PHPer,一定要定制一个适合自己的IDE,然后开始我们的路途吧... 1. 为不同的项目选定PHP版本 我们经常会遇到这样的场景,不同的项目 ...
- python+opencv读取视频,调用摄像头
引用 import cv2 import numpy 创建摄像头对象 cap = cv2.VideoCapture("videoTest/test1.mp4") #参数为视频文件目 ...
- javascript高级排序算法之快速排序(快排)
javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...
- SQLiteOpenHelper+ContentProvider的使用
效果图: PetDbHelper package com.example.admin.pets; import android.content.Context;import android.datab ...
- 面试题(一续Spring)
9.Spring体系结构和jar用途 参考https://blog.csdn.net/sunchen2012/article/details/53939253 spring官网给出了一张spring3 ...
- Python 使用 matplotlib绘制3D图形
3D图形在数据分析.数据建模.图形和图像处理等领域中都有着广泛的应用,下面将给大家介绍一下如何在Python中使用 matplotlib进行3D图形的绘制,包括3D散点.3D表面.3D轮廓.3D直线( ...
- flask 实现登录 登出 检查登录状态 的两种方法的总结
这里我是根据两个项目的实际情况做的总结,方法一(来自项目一)的登录用的是用户名(字符串)和密码,前后端不分离,用form表单传递数据:方法二用的是手机号和密码登录,前后端分离,以json格式传递数据, ...