高度并发的 Apache Async HTTP 客户端 IOReactor 问题

Highly Concurrent Apache Async HTTP Client IOReactor issues

应用说明:

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

问题描述

问题

忘了回答这个问题,但我在发布问题后大约一周才知道发生了什么:

  1. 某种错误配置导致 io-reactor 仅生成 2 个线程。

  2. 即使在提供更多反应器线程后,问题仍然存在。事实证明,我们的传出请求主要是 SSL。 Apache SSL 连接处理将核心处理传播到 JVM 的 SSL 设施,这对于每秒处理数千个 SSL 连接请求来说效率不够高。更具体地说,SSLEngine 中的一些方法(如果我没记错的话)是同步的。在高负载下进行线程转储显示 IORecator 线程在尝试打开 SSL 连接时相互阻塞。

  3. 甚至尝试以连接租用超时的形式创建压力释放阀也没有用,因为创建的积压工作量很大,导致应用程序无用。

  4. 将 SSL 传出请求处理卸载到 nginx 执行得更糟 - 因为远程端点抢先终止请求,无法使用 SSL 客户端会话缓存(JVM 实现也是如此)。

最后在整个模块前面放了一个信号量,在任何给定时刻将整个模块限制在 ~6000,这解决了问题。