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&register.ip=192.168.0.232&remote.timestamp=1554373603443&side=consumer&timeout=500000&timestamp=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线程模型的更多相关文章

  1. 第十章 dubbo线程模型

    一 netty的线程模型 在netty中存在两种线程:boss线程和worker线程. 1 boss线程 作用: accept客户端的连接: 将接收到的连接注册到一个worker线程上 个数: 通常情 ...

  2. dubbo线程模型配置

    首先了解一下dubbo线程模型 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,比如只是在内存中记个标识.则直接在IO线程上处理更快,因为减少了线程池调度. 但如果事件处理逻辑较慢,或者需要发 ...

  3. Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)

    文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...

  4. Dubbo学习笔记8:Dubbo的线程模型与线程池策略

    Dubbo默认的底层网络通讯使用的是Netty,服务提供方NettyServer使用两级线程池,其中 EventLoopGroup(boss) 主要用来接受客户端的链接请求,并把接受的请求分发给 Ev ...

  5. Dubbo -- 系统学习 笔记 -- 示例 -- 线程模型

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 线程模型 事件处理线程说明 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求 ...

  6. 【原创】Dubbo 2.7.5在线程模型上的优化

    这是why技术的第30篇原创文章 这可能是全网第一篇解析Dubbo 2.7.5里程碑版本中的改进点之一:客户端线程模型优化的文章. 先劝退:文本共计8190字,54张图.阅读之前需要对Dubbo相关知 ...

  7. 彻底搞懂 netty 线程模型

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...

  8. 面试官:Netty的线程模型可不只是主从多Reactor这么简单

    笔者看来Netty的内核主要包括如下图三个部分: 其各个核心模块主要的职责如下: 内存管理 主要提高高效的内存管理,包含内存分配,内存回收. 网通通道 复制网络通信,例如实现对NIO.OIO等底层JA ...

  9. 一文弄懂-Netty核心功能及线程模型

    目录 一. Netty是什么? 二. Netty 的使用场景 三. Netty通讯示例 1. Netty的maven依赖 2. 服务端代码 3. 客户端代码 四. Netty线程模型 五. Netty ...

随机推荐

  1. 好程序员分享居中一个float元素

    好程序员分享居中一个float元素,我们布局的时候,用margin来设置float元素的外边距来达到效果.对于,在文档流中的元素,我们很容易让它水平居中,只要给元素设置一个固定的宽度,用margin: ...

  2. ESP8266天线问题

    http://www.icxbk.com/ask/detail/28832.html 目前市面上常见的外接天线包括 1.FPC天线,就是一小块柔性PCB,上面走一个铜线,下方不覆铜,然后一般带一个贴纸 ...

  3. Strem_01

    import 'package:flutter/material.dart';import 'dart:async';import 'dart:ui'; void main()=>runApp( ...

  4. vue slot插槽的使用

    slot插槽的使用场景 父组件向子组件传递dom时会用到插槽   作用域插槽:当同一个子组件想要在不同的父组件里展示不同的状态,可以使用作用域插槽.展示的状态由父组件来决定   注:想要修改父组件向子 ...

  5. PostgreSql扩展Sql-动态加载共享库(C函数)

    基于 psql (PostgreSQL) 10.4 pg_language表定义了函数实现所使用的语言.主要支持了C语言和SQL语句.一些可选的语言包括pl/pgsql.tcl和perl. ligan ...

  6. 工具(3): 转换Excel表格到MarkDown:exceltk

    源码和下载: 0.1.3 mac: https://github.com/fanfeilong/exceltk/blob/master/pub/exceltk.0.1.3.pkg windows: h ...

  7. Yesterday when I was young

    Somehow, it seems the love I knew was always the most destructive kind 不知为何,我经历的爱情总是最具毁灭性的的那种 Yester ...

  8. git中如何撤销部分修改?

    以提问中修改了两个文件a.b为例,假设需要撤销文件a的修改,则修改后的两个文件: 1.如果没有被git add到索引区 git checkout a 便可撤销对文件a的修改 2.如果被git add到 ...

  9. Win10 登陆密码不正确(安全模式仍然启动不了)

    今天朋友重启Win10后,登陆密码显示不正确,是用了很多方法都不行 然后就瞎捣鼓就进去 进入BIOS将启动模式调为USB模式 重启启动不了后 再改回系统启动 就进去了(好神奇)

  10. centos7之vsftp安装和使用

    日常用作中,我们常用的是windows的共享,但是我们都知道windows运行不稳定.原来我们用的是centos6.5上的vsftpd,最近决定把centos6.*上的服务都移植到centos7上,好 ...