为什么 mod_proxy_protocol 或 ELB 导致 apache worker 数量过高?

Why is mod_proxy_protocol or ELB causing high apache worker count?

我们有一个遗留服务器集群 运行ning Apache 2.4,运行 我们的应用程序位于 ELB 后面。这个 ELB 有两个侦听器,一个 HTTP 和一个 HTTPS,后者终止于 ELB 并将常规 HTTP 流量发送到它后面的实例。这个 ELB 也关闭了 pre-open(这导致了繁忙的 worker 堆积)。在正常负载下,每个实例有 1-3 个忙碌的工作人员。

我们有一个新的服务器集群,我们正试图迁移到一个新的 ELB 后面。此迁移的目的是允许 SNI——为数千个域提供 TLS 流量。因此,此集群使用已在 ELB 级别启用的 mod_proxy_protocol。出于测试目的,我们一直在 DNS(Route 53)级别对流量进行加权,以将 30% 的流量发送到新的负载均衡器。即使在这么小的负载下,我们也会看到 5 – 10 个忙碌的工作人员,并且随着流量的增加而增加。

作为进一步测试,我们采用了其中一个新实例,禁用 proxy_protocol,并将其从新 ELB 移至旧 ELB,工作人员数量下降到平均水平,即 1-3 个繁忙的工作人员.这似乎表明 ELB 存在问题(HTTP 和 TCP 处理之间的差异?)或 mod_proxy_protocol.

我的问题:为什么在使用代理协议和新的 ELB 时我们的 apache worker 是繁忙的两倍?我认为,由于 TCP 侦听器是愚蠢的并且不对流量进行任何处理,因此它们会比 HTTP 侦听器更快,因此比主动“修改”通过它们的流量的 HTTP 侦听器消耗更少的工作时间。

感谢任何帮助我们诊断此问题的指导。

区别简单而显着:

HTTP 模式的 ELB 负责保持来自浏览器的空闲 keep-alive 连接,而不保持与实例的打开的相应连接。浏览器连接和 back-end 连接之间没有必要的关联 -- 可以重复使用后端连接。

在 TCP 模式下,它是 1:1。它必须是,因为 ELB 不能为 front-end 上的不同浏览器连接重用 back-end 连接——它不会解释管道中发生的事情。这对 TCP 来说总是正确的,但如果原因不是直观的,那么在启用代理协议的情况下应该特别明显。 PROXY "header" 实际上不是通常意义上的 "header" -- 它是序言。它只能在连接开始时发送,标识源地址和端口。连接一直持续到浏览器或服务器关闭它或超时为止。这是 1:1.

这不太可能适用于 Apache。

返回 HTTP 模式,等待一分钟。

This ELB also has pre-open turned off (it was causing a busy worker buildup).

我不知道你是怎么做到的——我从未见过它被记录下来,所以我认为这一定是通过支持请求完成的。

这似乎是一个完全解决错误问题的案例。不是拥有一些在您看来人为地高的连接数,您真正完成的只是人为地保持连接数低——最终,您实际上可能会损害您的性能和扩展能力。这些备用连接用于处理突发需求。如果您的实例太小而无法处理它们,那么我建议真正的问题在于:您的实例太小了。

另一种方法——这正是我用于我可怕的遗留 Apache-based 应用程序的解决方案(其中一个有一个 Apache 服务器位于总共大约 15 到 20 个不同的 ELB 后面——这是必要的,因为每个 ELB 都使用旧平台客户之一提供的证书卸载 SSL)——是 ELB 和 Apache 之间的 HAProxy。 HAProxy 每天可以在微小的实例上处理数百个连接和数百万个请求(我说的是微小的 -- t2.nano 和 t2.micro),并且它可以毫无问题地保持所有连接的活动ELB 在每次请求后关闭 Apache 连接......所以它在两个方向上都在优化。

当然,您也可以将 HAProxy 与 TCP 平衡器和代理协议一起使用——HAProxy 的作者也是代理协议的创建者 standard。您也可以 运行 在 Apache 的实例上而不是在单独的实例上。它在内存中是轻量级的 CPU 并且不会分叉。除了在 Lua 集成开发期间偶尔提交错误报告外,我与该项目无关。