在dubbo接口性能测试时,遇到一个十分焦急的问题,即运行脚本时,线程数正常起来,但是一直没有获取到执行的接口数据
一直等待,直至3min时,出现返回接口请求数据,但是响应时间均大于180s,这个时候服务端并没有流量,说明请求失败
问题排查
- 并发的线程数太高导致? 将各个线程组的并发线程数都改成1,再次执行,此时仍出现以上现象
- jmx脚本中有15个线程组,是否多个线程组相互影响导致?将线程组改成1个,再次执行,以上现象仍然出现
- jmx脚本中该dubbo接口请求响应导致?将dubbo接口请求改成简单的get请求,并同时在线程组中增加一个http请求,再次执行,http请求立马响应,dubbo请求仍然是以上现象
- dubbo服务的问题导致?重启dubbo服务,再次执行,发现一个现象,第一次请求的时候一直等待3min,接下来的请求可正常
抓包定位
在肉鸡中抓包,有两个问题点:
- 从发连接包到开始发数据包大概间隔3min(这个和前面体现的卡住时间一致)
105 2020-03-25 18:55:48.742387
10.200.0.251 172.26.0.50 TCP 76 15903 → 20880
[SYN] Seq=0 Win=1460 Len=0 MSS=1460 SACK_PERM=1 TSval=14623866 TSecr=0 WS=256
...
92982 2020-03-25 18:58:24.766870
172.26.11.57 10.200.0.251 TCP 812 20880 → 32265
[PSH, ACK] Seq=35 Ack=430 Win=30208 Len=744 TSval=82812964 TSecr=14779867
- 大概有2w+个连接包,过滤某一个服务实例的pod地址,发现有300个包,那么就是有100个连接
连接试验
使用命令 netstat -anlp | grep 20880 | wc-l
查看肉鸡dubbo接口连接数,连接数100
那是否一个线程组对应一个pod需要100个连接数?做了以下的实验:
- 2个线程组查看连接数:200
- 1个线程组每个线程组多个请求:100
- 2个线程组 10个实例数:2000
可以得出结论:连接数 = 线程组数 * 服务pod实例数 * 100
issue问题列表
查看issue
问题相关性不大。并不能解决我们对应的问题
插件源码定位
查看jmeter-dubbo源码
源码 DubboSample类中
可以看到 public static String DEFAULT_CONNECTIONS = "100";
,初始化CONNECTIONS=100
插件参数配置
connections配置
既然jmeter中有connections的默认值,是否在页面中哪里可以对该参数进行配置
在jmeter-dubbo插件中可以对该变量的设置,让我们看看该参数的说明
The maxmium connections of every provider.
for short connection such as rmi.
http and hessian,it's connection limit, but for long connection such as dubbo, it's connection count.
插件参数试验
对connection做一下配置验证
服务1个实例,1个线程组,connection 设置40 -> 连接数40
服务2个实例,1个线程组,connection 设置40 -> 连接数80
服务2个实例,2个线程组,connection 设置10 -> 连接数40
服务2个实例,1个线程组,线程组中两个请求sample,connection 设置40 -> 连接数80
服务1个实例,1个线程组,线程组中两个请求sample,1个sample connection 设置40,1个 sample connection 设置25-> 连接数65
基本符合以上的设置,但是有一点,即在一个线程组中,如果connection设置不一样,连接数为所有sample的connection的和
dubbo connection原理
在项目初始化的时候,RegistryDirectory#refreshInvoker 会将 provider 提供的接口刷新为 Invoker 类,如果接口未配置 connections 属性,则使用共享连接,如使用 dubbo 协议的方式 DubboProtocol#getClients
:
对于同一服务来源:
如果未配置 connections 属性,则单个消费者调用单个服务提供者之间共享一个连接,供所有接口使用
配置了 connections 属性,则针对该接口,独立创建配置的 n 个连接
Invoker 类如 DubboInvoker
,会持有一个连接数组 ExchangeClient[]
,每次调用远程接口前,会随机取出一个 ExchangeClient
:
实践尝试
将线程组中不需要并发执行较多线程的connect修改为5或者10,一台肉鸡中起100个线程,服务150个实例,可正常快速启动