申请说明:
根据以上各节,这里是我的光纤http客户端的调整(当然我使用的是单个实例):
PoolingNHttpClientConnectionManager connectionManager =
new PoolingNHttpClientConnectionManager(
new DefaultConnectingIOReactor(
IOReactorConfig.
custom().
setIoThreadCount(16).
setSoKeepAlive(false).
setSoLinger(0).
setSoReuseAddress(false).
setSelectInterval(10).
build()
)
);
connectionManager.setDefaultMaxPerRoute(32768);
connectionManager.setMaxTotal(131072);
FiberHttpClientBuilder fiberClientBuilder = FiberHttpClientBuilder.
create().
setDefaultRequestConfig(
RequestConfig.
custom().
setSocketTimeout(1500).
setConnectTimeout(1000).
build()
).
setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE).
setConnectionManager(connectionManager).
build();
打开文件的ulimits设置得非常高(软值和硬值均为131072)
kernel.printk = 8 4 1 7 kernel.printk_ratelimit_burst = 10 kernel.printk_ratelimit = 5 net.ipv4.ip_local_port_range = 8192 65535 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.optmem_max = 40960 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.core.netdev_max_backlog = 100000 net.ipv4.tcp_max_syn_backlog = 100000 net.ipv4.tcp_max_tw_buckets = 2000000 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_sack = 0 net.ipv4.tcp_timestamps = 1
问题描述
Pending
stat clibms也是一个空中飙升的30K挂起连接请求lsof
在java进程中,我可以看到它有成千上万的文件描述符,几乎所有文件描述符都在CLOSE_WAIT中(这是有意义的,因为I / O反应器线程死/停止运行,从不实际上关闭它们问题
答案 0 :(得分:0)
忘了回答这个问题,但在发布问题大约一个星期后我得到了什么:
有某种错过配置导致io-reactor只用2个线程产生。
即使提供更多反应器线程,问题仍然存在。事实证明,我们的传出请求主要是SSL。 Apache SSL连接处理将核心处理传播到JVM的SSL工具,这些工具很简单 - 每秒处理数千个SSL连接请求的效率不高。更具体地说,SSLEngine中的一些方法(如果我没记错的话)是同步的。在高负载下进行线程转储显示IORecator线程在尝试打开SSL连接时相互阻塞。
即使尝试以连接租约超时的形式创建压力释放阀也不起作用,因为创建的积压很大,导致应用无用。
卸载处理到nginx的SSL传出请求执行得更厉害 - 因为远程端点正在抢先终止请求,无法使用SSL客户端会话缓存(JVM实现也是如此)。
在整个模块前面放置一个信号量,在任何给定时刻将整个事件限制在~6000左右,这就解决了这个问题。