我可以在Prefork MPM下使用Apache mod_proxy作为连接池吗



摘要/问题:

我让Apache与Prefork MPM一起运行,运行php。我正试图使用Apache mod_proxy来创建一个反向代理,我可以通过它重新路由我的请求,这样我就可以使用Apache来进行连接池。示例impl:

httpd.conf:

SSLProxyEngine On
ProxyPass /test_proxy/ https://destination.server.com/ min=1 keepalive=On ttl=120

但是当我运行我的测试时,这是一个循环中的以下命令:

curl -G 'http://localhost:80/test_proxy/testpage'

它似乎没有重用连接。

经过进一步的阅读,听起来我没有获得连接池功能,因为我使用的是Prefork MPM而不是Worker MPM。因此,每次我向代理发出请求时,它都会启动一个具有自己的连接池(大小为1)的新进程,而不是使用维护自己连接池的单个工作进程。这种解释正确吗?


背景信息:

有一个外部服务器,我通过https为我运行的网站上的每一个页面发出请求。

协商SSL握手的成本越来越高,因为我使用php,它似乎不支持连接池——如果我的网站收到300个页面请求,他们必须对外部服务器进行300次SSL握手,因为每个脚本运行完后,连接就会关闭。

因此,我尝试在Apache下使用反向代理作为连接池,在php进程之间保持连接,这样我就不必经常进行SSL握手了。

给我这个想法的来源:

  • http://httpd.apache.org/docs/current/mod/mod_proxy.html
  • http://geeksnotes.livejournal.com/21264.html

首先,您的测试方法无法演示连接池,因为对于每个调用,都会产生一个curl客户端,然后它就会消亡。就像死人不怎么说话一样,一个死的过程无法保持联系。

您的客户端会困扰您的代理服务器。

Client ====== (A) =====> ProxyServer

让我们把这种连接称为A。你的代理服务器什么都不做,只是一种炫耀。这个英俊而勤奋的服务器非常谦逊,以至于他躲在后面。

Client ====== (A) =====> ProxyServer ====== (B) =====> WebServer

这里,如果我没有错的话,安全连接是A,而不是B,对吧?

重复我的第一点,在测试中,您将为每个请求创建一个单独的客户端。每个客户端都需要单独的连接。联系是发生在至少两方之间的事情。一侧离开,失去连接。

好吧,让我们现在忘记卷曲,一起看看我们真正想做什么。

我们希望A上有SSL,我们希望A侧的流量尽可能快。为了这个目的,我们已经分离了B面,所以它不会让A变得更慢,对吧?

连接池?A没有连接池这回事。每个客户端来来往往都会制造很多噪音。唯一能帮助您减少这种噪音的是"保持活动",这意味着在短时间内保持客户端的连接活动,这样这个客户端就可以请求此请求所需的其他文件。当我们完了,我们就完了。

对于B上的连接,将汇集连接;但这不会给您带来任何性能,因为在一台服务器上,您没有产生这部分噪音。

我们如何帮助这个系统更快地运行?

如果这两台服务器在同一台机器上,我们应该去掉炫耀服务器,继续使用我们辛勤工作的网络服务器。它给系统增加了很多不必要的工作。

如果这些是独立的机器,那么您至少可以从这个可怜的家伙那里获得加密(用于ssl)负载,从而对web服务器表现得很好。然而,你可以变得更好。

如果要在Apache上继续,请从mpm_prefork切换到mpm_worker。在300多个并发请求的情况下,这将更好地工作。我真的不知道你们硬件的容量;但是,如果处理300个请求很困难,我相信这个小小的更改将对您的系统有很大帮助。

如果你想拥有一个更加轻量级的系统,可以考虑将nginx作为Apache的替代方案。它很容易设置为使用PHP,并且会有更好的性能。

除了前端之外,还可以考虑检查数据库服务器。连接池将在这里发挥真正的作用。确保您的PHP安装配置为重用到数据库的连接。

此外,如果您在同一系统上托管静态文件,则将它们移到另一个web服务器上,或者通过将静态文件移到具有CDN的云系统(如AWS的S3+CloudFront或Rackspace的CloudFiles)来做得更好。即使没有CloudFront,S3也会让您感到高兴。Rackspace的解决方案由Akamai提供!

取出静态文件会让你的网络服务器"哦,发生了什么,这是什么沉默?哦,天哪!"因为你提到这是一个网站,网页在大多数情况下每个动态生成的html页面都有许多静态文件。

我希望你能把这个可怜的家伙从杀人的工作中救出来。

Prefork仍然可以为每个进程的每个后端服务器池1个连接。

Prefork不一定为每个前端请求创建一个新的进程,服务器进程本身是"池"的,行为取决于例如MinSpareServers/MaxSpareServers和朋友。

为了最大限度地提高工作前进程拥有后端连接的频率,请避免使用非常高或非常低的maxspareservers或非常高的minspareserver,因为这会导致"新"进程接受新连接。

您可以在LogFormat指令中记录%p,以帮助了解进程被重用的频率。

在我的案例中,问题是,由于后端服务器Apache在每个HTTPS请求结束时关闭SSL连接,因此反向代理和后端服务器之间的连接池没有发生。

后端Apache服务器之所以这样做,是因为httpd.conf:中存在以下指令

SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

当后端服务器通过反向代理连接时,此指令没有意义,并且可以从后端服务器配置中删除。

最新更新