博客
关于我
Dubbo-线程池调优实战分析
阅读量:344 次
发布时间:2019-03-04

本文共 2118 字,大约阅读时间需要 7 分钟。

Dubbo的线程池压测调优

dubbo的服务提供者端一共包含了两类线程池,一类叫做io线程池,还有一类叫做业务线程池,它们各自有着自己的分工,如下图所示

在这里插入图片描述

dubbo在服务提供方中有io线程池和业务线程池之分。可以通过调整相关的dispatcher参数来控制将请求处理交给不同的线程池处理。(下边列举工作中常用的几个参数:)

all:将请求全部交给业务线程池处理(这里面除了日常的消费者进行服务调用之外,还有关于服务的心跳校验,连接事件,断开服务,响应数据写回等)

execution:会将请求处理进行分离,心跳检测,连接等非业务核心模块交给io线程池处理,核心的业务调用接口则交由业务线程池处理。

假设说我们的dubbo接口只是一些简单的逻辑处理,例如说下方这类:

@Service(interfaceName = "msgService")public class MsgServiceImpl implements MsgService {       @Override    public Boolean sendMsg(int id, String msg)  {               System.out.println("msg is :"+msg);            return true;    }}

并没有过多的繁琐请求,并且我们手动设置线程池参数

dubbo.protocol.threadpool=fixeddubbo.protocol.threads=10dubbo.protocol.accepts=5

当线程池满了的时候,服务会立马进入失败状态,此时如果需要给provider设置等待队列的话可以尝试使用queues参数进行设置。

dubbo.protocol.queues=100

但是这个设置项虽然看似能够增大服务提供者的承载能力,却并不是特别建议开启,因为当我们的provider承载能力达到原先预期的限度时,通过请求堆积的方式继续请求指定的服务器并不是一个合理的方案,合理的做法应该是直接抛出线程池溢出异常,然后请求其他的服务提供者。

测试环境:

Mac笔记本,jvm:-xmx 256m -xms 256m

接着通过使用jmeter进行压力测试,发现一秒钟调用100次(大于实际的业务线程数目下,线程池并没有发生溢出情况)。这是因为此时dubbo接口中的处理逻辑非常简单,这么点并发量并不会造成过大影响。(几乎所有请求都能正常抗住)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4Zi52J8-1601426396913)(http://www.ideal123.cn:9000/files/img/1598148942073.png "http://www.ideal123.cn:9000/files/img/1598148942073.png")]

在这里插入图片描述

但是假设说我们的dubbo服务内部做了一定的业务处理,耗时较久,例如下方:

@Service(interfaceName = "msgService")public class MsgServiceImpl implements MsgService {       @Override    public Boolean sendMsg(int id, String msg) throws InterruptedException {               System.out.println("msg is :"+msg);            Thread.sleep(500);            return true;    }}

此时再做压测,解果就会不一样了。

在这里插入图片描述

此时大部分的请求都会因为业务线程池中的数目有限出现堵塞,因此导致大量的rpc调用出现异常。可以在console窗口看到调用出现大量异常:

在这里插入图片描述

将jmeter的压测报告进行导出之后,可以看到调用成功率大大降低,

在这里插入图片描述

也仅仅只有10%左右的请求能够被成功处理,这样的服务假设进行了线程池参数优化之后又会如何呢?

1秒钟100个请求并发访问dubbo服务,此时业务线程池专心只处理服务调用的请求,并且最大线程数为100,服务端最大可接纳连接数也是100,按理来说应该所有请求都能正常处理

dubbo.protocol.threadpool=fixeddubbo.protocol.dispatcher=executiondubbo.protocol.threads=100dubbo.protocol.accepts=100

还是之前的压测参数,这回所有的请求都能正常返回。

在这里插入图片描述

ps:提出一个小问题,从测试报告中查看到平均接口的响应耗时为:502ms,也就是说其实dubbo接口的承载能力估计还能扩大个一倍左右,我又尝试加大了压测的力度,这次看看1秒钟190次请求会如何?(假设线程池100连接中,每个连接对请求的处理耗时大约为500ms,那么一秒时长大约能处理2个请求,但是考虑到一些额外的耗时可能达不到理想状态那么高,因此设置为每秒190次(190 <= 2*100)请求的压测)

在这里插入图片描述

但是此时发现请求的响应结果似乎并没有这么理想,这次请求响应的成功率大大降低了。

在这里插入图片描述
其实主要原因是当线程池满了的时候,服务会立马进入失败状态,而jmeter产生的压测线程数目并不是均匀的,可能190个线程的80%是在1s内的后0.5s中产生,这种情况下是会造成dubbo服务承载失败的。

转载地址:http://zeve.baihongyu.com/

你可能感兴趣的文章
Navicat向sqlserver中插入数据时提示:当 IDENTITY_INSERT 设置为 OFF 时,不能向表中的标识列插入显式值
查看>>
Navicat因导入的sql文件中时间数据类型有参数而报错的原因(例:datetime(3))
查看>>
Navicat如何连接MySQL
查看>>
navicat导入.sql文件出错2006- MySQLserver has gone away
查看>>
Navicat导入海量Excel数据到数据库(简易介绍)
查看>>
Navicat工具Oracle数据库复制 or 备用、恢复功能(评论都在谈论需要教)
查看>>
Navicat工具中建立数据库索引
查看>>
navicat工具查看MySQL数据库_表占用容量_占用空间是多少MB---Linux工作笔记048
查看>>
navicat怎么导出和导入数据表
查看>>
Navicat怎样同步两个数据库中的表
查看>>
Navicat怎样筛选数据
查看>>
Navicat报错connection is being used
查看>>
Navicat报错:1045-Access denied for user root@localhost(using passwordYES)
查看>>
Navicat控制mysql用户权限
查看>>
navicat操作mysql中某一张表后, 读表时一直显示正在载入,卡死不动,无法操作
查看>>
Navicat连接mysql 2003 - Can't connect to MySQL server on ' '(10038)
查看>>
Navicat连接mysql数据库中出现的所有问题解决方案(全)
查看>>
Navicat连接Oracle出现Oracle library is not loaded的解决方法
查看>>
Navicat连接Oracle数据库以及Oracle library is not loaded的解决方法
查看>>
Navicat连接sqlserver提示:未发现数据源名并且未指定默认驱动程序
查看>>