Apache代理不会在使用预派或工作器MPM时进行连接重用

3

背景信息

我们有一台Dell R620电信企业应用服务器,运行在RHEL 5平台上,并部署了Apache Web服务器和OCCAS应用服务器。我们有专有的电话作为客户端连接到应用服务器,并使用Apache处理所有基于HTTP的请求。Apache服务器被配置为代理/转发请求到OCCAS。

问题

专有的电话会在启动时发送大约350个HTTP请求,在35秒内即每秒发送大约10个请求。我们可以清楚地看到电话与Apache之间的连接正在重用,而Apache与OCCAS之间的连接没有重用连接,导致每个请求创建一个新的连接。Apache与OCCAS之间的连接被Apache /代理关闭(我们从代理看到FIN),服务请求后就关闭了。因此,在所有350个请求都得到服务后,在一分钟内我们可以看到350个处于TIME_WAIT状态的套接字。我们的系统应该可以处理500个这样的电话。现在,如果您能想象当所有500个电话同时做出350个请求时,将需要175,000(350 * 500)个临时端口!因此,我试图使Apache代理与OCCAS之间的连接重用起来,但遇到了问题。

我已经发布了我们拥有的配置以及我们尝试并失败的不同方法,以使连接重用起作用。

我们的配置

1)我们系统中/etc/httpd/conf/httpd.conf 中配置的prefork和worker MPM如下所示,并且我们正在使用默认的prefork MPM。

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
</IfModule>

<IfModule worker.c>
StartServers         8
MaxClients         150
MinSpareThreads      5
MaxSpareThreads     20
ThreadsPerChild    256
MaxRequestsPerChild  4000
</IfModule>

2)/etc/httpd/conf/httpd.conf中与Keepalive相关的参数如下:

[root@host ~]# grep -i keepalive /etc/httpd/conf/httpd.conf | grep -v "#"
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
[root@host ~]#

3) 代理配置如下:

<VirtualHost *:80>

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

<Location /ds-webservice>
ProxyPass         http://{IP address of local host}:8001/ds-webservice retry=0
ProxyPassReverse  http://{IP address of local host}:8001/ds-webservice
</Location>
.
.
# Few more similar ProxyPass
.
.
</VirtualHost>

4) 我们使用默认的prefork Apache:

[root@host ~]# httpd -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

尝试但未能实现连接重用的测试

测试1) 我们注意到mod_proxy在转发请求时发送了“Connection: Keep-alive”标头(但没有发送“Keep-alive”标头本身),而OCCAS没有响应“Connection”或“Keep-alive”标头。我们最初怀疑Apache不喜欢在缺少这些标头的情况下的响应。因此,作为一个实验,我们将请求转发到另一个Apache中,在那里我们确实从其他Apache收到了响应的“Connection”或“Keep-alive”标头,但mod_proxy仍然没有进行连接重用。因此,我们确认是mod_proxy存在问题(或者可能是我们方面的某些错误配置)。

测试2) 经过一些研究,我们发现了一个关于2.2.0中使用prefork进行连接重用的错误报告-https://issues.apache.org/bugzilla/show_bug.cgi?id=38602。错误38602已在2.2.1中修复。然而,根据Can I use Apache mod_proxy as a connection pool, under the Prefork MPM?的帖子,我们发现即使升级后问题似乎仍然存在。因此,为了确保,我们将Apache从2.2.3升级到2.2.26,但mod_proxy仍未进行连接重用。

测试3) 我们尝试使用不同的ProxyPass参数进行了几次测试(在httpd.conf中没有更改任何内容),但没有一个有帮助,即mod_proxy没有进行连接重用: 注意:除(7)之外,我们在测试中在“ProxyPass http://{本地主机的IP地址}:8001/ds-webservice”旁添加了以下参数。
1. retry=0 (我们的默认配置)
2. disablereuse=OFF
3. max=256 retry=0
4. proxyto=80
5. retry=0 keepalive=ON
6. retry=300 smax=5 max=20 ttl=120
7. 最后,我们在代理配置中添加了特定于keep-alive的参数,希望它会覆盖http.conf中的keep-alive参数:

<VirtualHost *:80>

Timeout 300
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 100
ProxyRequests Off

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

<Location /ds-webservice>
ProxyPass         http://{IP address of local host}:8001/ds-webservice retry=0
ProxyPassReverse  http://{IP address of local host}:8001/ds-webservice
</Location>
.
.
# Few more similar ProxyPass
.
.
</VirtualHost>

根据 Can I use Apache mod_proxy as a connection pool, under the Prefork MPM? 这篇文章,我们在2.2.26上通过使用httpd.worker从prefork Apache切换到worker Apache,但mod_proxy没有进行连接复用。
看起来我们在这里缺少了一些非常基本的东西。如果ProxyPass或prefork配置有任何问题,请指点一下我们吧,因为它们都是相关的。任何指针都将非常有帮助。
提前感谢你!
敬礼 Goutham Prasad
1个回答

1
很可能你的客户正在使用HTTP协议1.0进行请求(在这种情况下,需要通过头文件显式启用keepalives),或者请求或响应正在使用“Connection: close”头关闭连接。请参见http://en.wikipedia.org/wiki/HTTP_persistent_connection 最好的方法是通过数据包跟踪发布以下内容的标题:
1.客户端到代理的请求 2.代理到OCCAS的请求 3.OCCAS到代理的响应
这将使您看到正在使用哪个协议版本和标题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接