netty worker线程数量_Dubbo线程模型

516d217a2e0f03c0113c7bee1a92c825.png
Dubbo中线程池的应用还是比较广泛的,按照consumer端到provider的RPC的方向来看,consumer端的应用业务线程到netty线程、consuemr端dubbo业务线程池,到provider端的netty boss线程、worker线程和dubbo业务线程池等。这些线程各司其职相互配合,共同完成dubbo RPC服务调用,理解dubbo线程模型对于学习Dubbo原理很有帮助。

dubbo线程模型包括线程模型策略和dubbo线程池策略两个方面,下面就依次进行分析。

dubbo线程模型

Dubbo默认的底层网络通信使用的是Netty,服务提供方NettyServer使用两级线程池,其中EventLoopGroup(boss)主要用来接收客户端的链接请求,并把完成TCP三次握手的连接分发给EventLoopGroup(worker)来处理,注意把boss和worker线程组称为I/O线程,前者处理IO连接事件,后者处理IO读写事件。

设想下,dubbo provider端的netty IO线程是如何处理业务逻辑呢?如果处理逻辑较为简单,并且不会发起新的I/O请求,那么直接在I/O线程上处理会更快,因为这样减少了线程池调度与上下文切换的开销,毕竟线程切换还是有一定成本的。如果逻辑较为复杂,或者需要发起网络通信,比如查询数据库,则I/O线程必须派发请求到新的线程池进行处理,否则I/O线程会被阻塞,导致处理IO请求效率降低。

那Dubbo是如何做的呢?

Dubbo中根据请求的消息类是直接被I/O线程处理还是被业务线程池处理,Dubbo提供了下面几种线程模型:

c1f78c142051af5fc08ae35d9dcfdbe3.png
  • all(AllDispatcher类):所有消息都派发到业务线程池,这些消息包括请求、响应、连接事件、断开事件等,响应消息会优先使用对于请求所使用的线程池。
  • direct(DirectDispatcher类):所有消息都不派发到业务线程池,全部在IO线程上直接执行。
  • message(MessageOnlyDispatcher类):只有请求响应消息派发到业务线程池,其他消息如连接事件、断开事件、心跳事件等,直接在I/O线程上执行。
  • execution(ExecutionDispatcher类):只把请求类消息派发到业务线程池处理,但是响应、连接事件、断开事件、心跳事件等消息直接在I/O线程上执行。
  • connection(ConnectionOrderedDispatcher类):在I/O线程上将连接事件、断开事件放入队列,有序地逐个执行,其他消息派发到业务线程池处理。

dubbo线程池可选模型较多,下面以DirectDispatcher类进行分析,其他流程类似就不在赘述。

public class DirectChannelHandler extends WrappedChannelHandler {@Overridepublic void received(Channel channel, Object message) throws RemotingException {ExecutorService executor = getPreferredExecutorService(message);if (executor instanceof ThreadlessExecutor) {try {executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));} catch (Throwable t) {throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);}} else {handler.received(channel, message);}}
}

DirectDispatcher类重写了received方法,注意 ThreadlessExecutor 被应用在调用 future.get() 之前,先调用 ThreadlessExecutor.wait(),wait 会使业务线程在一个阻塞队列上等待,直到队列中被加入元素。很明显,provider侧调用getPreferredExecutorService(message)返回的不是ThreadlessExecutor,所以会在当前IO线程执行执行。

其他事件,比如连接、异常、断开等,都是在WrappedChannelHandler中默认实现:执行在当前IO线程中执行的,代码如下:
@Override
public void connected(Channel channel) throws RemotingException {handler.connected(channel);
}
@Override
public void disconnected(Channel channel) throws RemotingException {handler.disconnected(channel);
}
@Override
public void sent(Channel channel, Object message) throws RemotingException {handler.sent(channel, message);
}
@Override
public void caught(Channel channel, Throwable exception) throws RemotingException {handler.caught(channel, exception);
}

dubbo线程模型策略

了解了dubbo线程模型之后,小伙伴是不是该问:

既然有那么多的线程模型策略,dubbo线程模型具体使用的是什么策略呢?

从netty启动流程来看,初始化NettyServer时会进行加载具体的线程模型,代码如下:

public NettyServer(URL url, ChannelHandler handler) throws RemotingException {super(ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME), ChannelHandlers.wrap(handler, url));
}
public static ChannelHandler wrap(ChannelHandler handler, URL url) {return ChannelHandlers.getInstance().wrapInternal(handler, url);
}
protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) {return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class).getAdaptiveExtension().dispatch(handler, url)));
}

这里根据URL里的线程模型来选择具体的Dispatcher实现类。在此,我们再提一下Dubbo提供的Dispatcher实现类,其默认的实现类是all,也就是AllDispatcher类。既然Dispatcher是通过SPI方式加载的,也就是用户可以自定义自己的线程模型,只需实现Dispatcher类然后配置选择使用自定义的Dispatcher类即可。

dubbo线程池策略

dubbo处理流程,为了尽量早地释放Netty的I/O线程,某些线程模型会把请求投递到线程池进行异步处理,那么这里所谓的线程池是什么样的线程池呢?

其实这里的线程池ThreadPool也是一个扩展接口SPI,Dubbo提供了该扩展接口的一些实现,具体如下:
  • FixedThreadPool:创建一个具有固定个数线程的线程池。
  • LimitedThreadPool:创建一个线程池,这个线程池中的线程个数随着需要量动态增加,但是数量不超过配置的阈值。另外,空闲线程不会被回收,会一直存在。
  • EagerThreadPool:创建一个线程池,在这个线程池中,当所有核心线程都处于忙碌状态时,将创建新的线程来执行新任务,而不是把任务放入线程池阻塞队列。
  • CachedThreadPool:创建一个自适应线程池,当线程空闲1分钟时,线程会被回收;当有新请求到来时,会创建新线程。

知道了这些线程池之后,那么是什么时候进行SPI加载对应的线程池实现呢?具体是在dubbo 线程模型获取对应线程池时进行SPI加载的,具体逻辑在方法 org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository#createExecutor中:

private ExecutorService createExecutor(URL url) {return (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);
}
@SPI("fixed")
public interface ThreadPool {@Adaptive({THREADPOOL_KEY})Executor getExecutor(URL url);
}

从代码来看,默认的线程池策略是fixed模式的线程池,其coreSize默认为200,队列大小为0,其代码如下:

public class FixedThreadPool implements ThreadPool {@Overridepublic Executor getExecutor(URL url) {String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);int threads = url.getParameter(THREADS_KEY, DEFAULT_THREADS);int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,queues == 0 ? new SynchronousQueue<Runnable>() :(queues < 0 ? new LinkedBlockingQueue<Runnable>(): new LinkedBlockingQueue<Runnable>(queues)),new NamedInternalThreadFactory(name, true), new AbortPolicyWithReport(name, url));}
}
注:其他线程池策略和FixedThreadPool类似,只不过线程池参数不同而已,这里不再赘述。

小结

从dubbo提供的几种线程模型和线程池策略来看,基本上能满足绝大多数场景的需求了,由于dubbo线程模型和线程池策略都是通过SPI的方式进行加载的,因此如果业务上需要,我们完全可以自定义对应的线程模型和线程池策略,只需要配置下即可。

推荐阅读

Dubbo RPC在consumer端是如何跑起来的​mp.weixin.qq.com
896e6b7be7fc44b5cb0e1b3e4cf94907.png
dubbo版的"明朝那些事儿"​mp.weixin.qq.com
3d81c1f58dc29d5be0d7485309d0b6a7.png
责任链的2种实现方式,你更pick哪一种​mp.weixin.qq.com
ddbe6ca56c2aefea33cb978b8b1325a3.png
网络数据是如何传递给进程的​mp.weixin.qq.com
71dcc09394eb1e8b255b2e39f188f209.png
Linux管道那些事儿​mp.weixin.qq.com
86a999847eda443536af8a51b2996c25.png
从socket api看网络通信流程​mp.weixin.qq.com
ddbe6ca56c2aefea33cb978b8b1325a3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

function click_click事件的累加问题解决

click事件的 累加问题解决&#xff1a;$判断是否隐藏&#xff1a;hidden.c>span 只包含儿子.c span 包含儿子和孙子data-*嵌入自定义数据 .data(to)获取数据remove是移除标签 delete删除数组元素each()函数$(".layui-table-total .layui-table-cell").each(functi…

知道python语言应用2020答案_热点:大学moocPython语言基础与应用答案

2020年智慧树网课答案为您详细解读azMisb热点&#xff1a;大学moocPython语言基础与应用答案的详情,题主的教授应该是想要同学们找出一个值得研究和讨论的theory&#xff0c;简单来说就是你论文探讨的中心。然后需要你们定topic&#xff0c;然后搜索大量靠谱的资料&#xff0c;…

timestamp 转换 date mysql_MySQL时间函数 | 时间戳和日期之间得转换

一、时间戳转日期select FROM_UNIXTIME(1606028010, %Y-%m-%d %H:%i:%s);二、日期转时间戳select unix_timestamp(2018-01-15 09:45:16);三、时间戳格式化十位时间戳转为固定格式(yyyy-MM-dd HH:mm:ss)日期1.格式规定%M 月名字(January……December)%W 星期名字(Sunday……Satu…

python是一种动态语言这意味着_Python如何能成为全球最受欢迎的编程语言?该不该学Python?...

全文共3304字&#xff0c;预计学习时长10分钟 图源&#xff1a;(Python logo courtesy of https 有一种语言在过去十年受喜爱度一路飙升&#xff0c;成为最受欢迎的一种编程语言&#xff0c;它是谁&#xff1f; 千呼万唤始出来&#xff0c;没错&#xff0c;它就是我们的老弟Pyt…

python处理csv文件案例_让繁琐的工作自动化——python处理CSV文件

让繁琐的工作自动化——python处理CSV文件CSV&#xff1a;CSV文件是一种简化的电子表格&#xff0c;不同于Excle(二进制文件)&#xff0c;CSV是纯文本文件。1.环境python3.8pycharm2020.12.读取本期实例数据haha,18,10.0jiji,16,12.1lala,17,11.9papa,11,13.3首先导入csv模块&a…

python实现坐标求取_根据相机位姿求指定点的世界坐标及其python实现

Authorshaniadolphin求解目的本文将展示位姿估计的一种应用&#xff0c;即通过单目相机对环境进行测量。简单来说&#xff0c;本文的工作就是利用下面的两幅图&#xff0c;在已知P1、P2、P3、P4四点世界坐标的情况下&#xff0c;计算出其它点的世界坐标。如图所示&#xff0c;一…

c# treeview查找并选中节点_最通俗易懂的二叉查找树(BST)详解

原来来自 呆萌数据结构-06二叉查找树​imoegirl.com二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;简写BST&#xff0c;是满足某些条件的特殊二叉树。任何一个节点的左子树上的点&#xff0c;都必须小于当前节点。任何一个节点的右子树上的点&#xff0c;都…

服务器损坏mysql修复_云服务器mysql数据库损坏修复mysql

有的时候因为各种原因导致mysql数据库损坏,我们可以使用mysql自带的mysqlcheck命令来快速修复所有的数据库或者特定的数据库,检查优化并修复所有的数据库.1.先在运行中输入CMD,启动命令行.2.进入Mysql的Bin目录&#xff1a;D:\VHostData\MySQL5.1\bin,(这个路径在数据库的安装目…

bootstrap jquery alert_bootstrap第七课

bootstrap 模态框bootstrap是一个非常酷的前端开发框架&#xff0c;它可以大大的简化我们日常开发当中的功能与样式。它有非常漂亮的css组件和非常实用的控件供我们使用。接下来我们来看看bootstrap的内容吧&#xff01;首先大家要引入bootstrap的css和js可以在这里下载&#x…

java 闭包_公司新来的女实习生问我什么是闭包?

作者&#xff1a;霍语佳来源&#xff1a;前端食堂观感度&#xff1a;?????口味&#xff1a;冰镇西瓜烹饪时间&#xff1a;20min撩妹守则第一条&#xff0c;女孩子都喜欢童话故事。那就先来讲一个童话故事~// 有一个公主// 她生活在一个充满冒险的奇妙世界里// 她遇见了她的…

java org.apache.http_org.apache.http jar包下载-org.apache.http.jar包下载 --pc6下载站

org.apache.http.jar包是一款十分常用的jar包如果没有org.apache.http.jar包Apache与http的链接将会出现错误等现象马上下载org.apache.http.jar包。。相关软件软件大小版本说明下载地址org.apache.http.jar包是一款十分常用的jar包,如果没有org.apache.http.jar包,Apache与htt…

网络连接异常、网站服务器失去响应_网站常见故障解决办法

网站在运行过程中&#xff0c;常常遇到各种服务器问题&#xff0c;虽然有服务器厂商的维护&#xff0c;但是往往耗时耗工小编对常见的服务器问题&#xff0c;进行了归纳整理&#xff0c;下面跟各位分享一下。常见故障分析一、恶意攻击在我平时管理网站时&#xff0c;可能会遭到…

python3 sleep 并发_python异步编程之asyncio(百万并发)

点击上方蓝字关注我们目录[python 异步编程之 asyncio(百万并发)]一、asyncio二、aiohttp前言&#xff1a;python 由于 GIL(全局锁)的存在&#xff0c;不能发挥多核的优势&#xff0c;其性能一直饱受诟病。然而在 IO 密集型的网络编程里&#xff0c;异步处理比同步处理能提升成…

【Spring实战】02 配置多数据源

文章目录 1. 配置数据源信息2. 创建第一个数据源3. 创建第二个数据源4. 创建启动类及查询方法5. 启动服务6. 创建表及做数据7. 查询验证8. 详细代码总结 通过上一节的介绍&#xff0c;我们已经知道了如何使用 Spring 进行数据源的配置以及应用。在一些复杂的应用中&#xff0c;…

windows查看usb信息命令_【VPS】Linux VPS查看系统信息命令大全

本文转自老左笔记&#xff0c;自用mark系统# uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看计算机名 # lspci -tv # 列出所有PCI设备 # lsusb -tv # 列出所有USB设备 # lsmod # 列出加…

无法初始化sftp协议。主机是sftp服务器吗?_WinSCP v5.15.3 免费的 开源图形化 SFTP 客户端...

WinSCP 是一个 Windows 环境下使用的 SSH 的开源图形化 SFTP 客户端。同时支持 SCP 协议。它的主要功能是在本地与远程计算机间安全地复制文件&#xff0c;并且可以直接编辑文件。主要功能WinSCP 可以执行所有基本的文件操作&#xff0c;例如下载和上传。同时允许为文件和目录重…

java中组合_java中组合模式详解和使用方法

组合模式(Composite Pattern)&#xff0c;又叫部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设计模式属于结构型模式&#xff0c;它创建了对象组的树形结构。这种模式创…

道客巴巴vip账号共享2020_腾讯视频VIP怎么两个手机通用?

理论上来说&#xff0c;腾讯视频VIP可以同时在3个设备上登录&#xff0c;但只能在2个设备上同时播放视频。这也就意味着&#xff0c;腾讯视频VIP可以在两个手机上同时使用。腾讯视频VIP基本可以分为微信区、QQ区&#xff0c;两者并不互通。近期腾讯视频手机端修改了登录规则&am…

java 字符串是对象吗_解析Java中的String对象的数据类型

解析Java中的String对象的数据类型2007-06-06eNet&Ciweek1. 首先String不属于8种基本数据类型&#xff0c;String是一个对象。因为对象的默认值是null&#xff0c;所以String的默认值也是null&#xff1b;但它又是一种特殊的对象&#xff0c;有其它对象没有的一些特性。2. …

7-7 六度空间 (30分)_现役球员中,谁最可能成下一位30000分先生?3大前十巨星没戏...

想要在NBA联盟得到3万分有多难&#xff1f;从联盟成立至今的70多年中&#xff0c;总得分超过3万分的球员一共只有7位&#xff0c;他们分别是贾巴尔、马龙、詹姆斯、科比、乔丹、诺维茨基和张伯伦&#xff0c;剩下的强如大鲨鱼、艾弗森都没能完成这一壮举&#xff0c;那现役球员…