Vert.x HTTP Client连接数超出MaxPoolSize限制问题咨询
我有一个应用包含8个Verticle,每个Verticle都运行在独立线程中,并且各自实例化了一个WebClient。配置WebClientOptions时,我设置了setMaxPoolSize(10),代码如下:
WebClientOptions webClientOptions = new WebClientOptions().setMaxPoolSize(10);
但在生产主机上执行命令:
/usr/sbin/ss -o state established -tn | tail -n +2 | awk '{ print $4 }' | sort |uniq -c | sort -n
检查后发现,单个IP:Port的连接数超过了10个。
问题1:MaxPoolSize是否为整个应用的全局设置?
嘿,这个问题我碰到过好几次了,给你理清楚关键点:
首先直接给你答案:setMaxPoolSize绝对不是应用全局的设置,它是每个WebClient实例独有的配置。
你现在的情况是8个Verticle各自初始化了一个WebClient,每个WebClient都带着你设置的setMaxPoolSize(10)——这意味着每个WebClient都会维护自己独立的连接池,每个池对单个目标IP:Port最多能开10个连接。那8个这样的池加起来,单个目标的总连接数自然就能到80个,这完全符合你看到的"超过10个"的现象。
那为什么Vert.x要这么设计?其实是为了让不同的业务模块(比如你的各个Verticle)可以独立管控自己的HTTP客户端资源,避免某一个模块的请求把连接池占满影响其他模块。但如果你的需求是整个应用对同一个目标的连接数有全局上限,那正确的做法应该是:在应用启动时创建一个全局共享的WebClient实例,然后把这个实例注入到所有Verticle里使用。这样一来,setMaxPoolSize(10)就会成为这个全局实例的连接池上限,整个应用对单个目标的连接数就会被控制在10以内。
另外再补个小细节:setMaxPoolSize的限制是针对**单个目标端点(也就是具体的IP:Port)**的,不是这个WebClient的总连接数。举个例子,如果你设置了10,那这个WebClient对A服务器(192.168.1.1:80)最多开10个连接,对B服务器(192.168.1.2:80)也能开10个,两者互不影响。
最后给你个实操建议:如果你的8个Verticle都是做类似的HTTP请求工作,那共享一个WebClient绝对是更优的选择——既能统一控制连接数,还能减少不必要的资源开销,毕竟每个WebClient都有自己的底层资源占用。
内容的提问来源于stack exchange,提问作者Michael P

