问题从 Stackoverflow 移出
我有一个处理客户端请求的 PHP 脚本。我应该能够处理 1000 个并发请求(使用 apache 基准)。当我当前运行 300 个并发请求的 apache 基准时,我能够处理所有请求。但是当我超过 300 个标记时,apache 无法处理它。(它退出时显示 apr_socket_recv:对等方重置连接 (104) )
这是 apache 错误日志。
[Thu Oct 29 11:20:34.984542 2015] [mpm_prefork:notice] [pid 6244] AH00163: Apache/2.4.7 (Ubuntu) PHP/5.5.9-1ubuntu4.13 configured -- resuming normal operations
[Thu Oct 29 11:20:34.984581 2015] [core:notice] [pid 6244] AH00094: Command line: '/usr/sbin/apache2'
[Thu Oct 29 11:21:38.638943 2015] [mpm_prefork:error] [pid 6244] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
这是 mpm prefork 配置 -
<IfModule mpm_prefork_module>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
MaxRequestWorkers 256
MaxConnectionsPerChild 4
</IfModule>
从上面的配置来看,我可以同时处理 256 * 4 > 1000 个请求。我目前使用的是一台 8 核机器,内存为 16GB。
我的 Apache 服务器可以处理 1000 个并发请求吗?
有关我的 PHP 代码的更多详细信息
收到客户端请求后,我的 php 脚本会启动一个 python 脚本。这个 python 脚本使用 python 多处理功能并行远程登录 50 台不同的机器。平均而言,完成一个请求需要 0.5 秒。
编辑
根据 shodanshok 的建议,我将 mpm worker conf 文件更改为:-
<IfModule mpm_prefork_module>
ServerLimit 300
StartServers 50
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 300
MaxConnectionsPerChild 0
</IfModule>
但基准测试仍然没有完成,它很早就退出了。这是我在 Apache 日志中发现的。
[Thu Oct 29 12:14:42.372184 2015] [mpm_prefork:notice] [pid 29261] AH00169: caught SIGTERM, shutting down
[Thu Oct 29 12:14:42.913499 2015] [mpm_prefork:notice] [pid 1397] AH00163: Apache/2.4.7 (Ubuntu) PHP/5.5.9-1ubuntu4.13 configured -- resuming normal operations
[Thu Oct 29 12:14:42.913539 2015] [core:notice] [pid 1397] AH00094: Command line: '/usr/sbin/apache2'
答案1
你误解了什么MaxRequestWorkers
和MaxConnectionsPerChild
做什么。从手册页:
MaxRequestWorkers 指令设置同时处理的请求数限制。任何超过 MaxRequestWorkers 限制的连接尝试通常都会排队,最高数量取决于 ListenBacklog 指令。一旦子进程在另一个请求结束时被释放,该连接就会得到服务。
对于非线程服务器(即 prefork),MaxRequestWorkers 表示将启动用于处理请求的最大子进程数。默认值为 256;要增加该值,还必须增加 ServerLimit。
对于线程和混合服务器(例如事件或工作器),MaxRequestWorkers 限制了可用于为客户端提供服务的线程总数。对于混合 MPM,默认值为 16(ServerLimit)乘以 25(ThreadsPerChild)。因此,要将 MaxRequestWorkers 增加到需要超过 16 个进程的值,您还必须提高 ServerLimit。
和
MaxConnectionsPerChild 指令设置单个子服务器进程将处理的连接数限制。在 MaxConnectionsPerChild 个连接之后,子进程将终止。如果 MaxConnectionsPerChild 为 0,则该进程将永不终止。
简而言之,在 prefork 模式下MaxRequestWorkers
,全部的允许的并发连接数。MaxConnectionsPerChild
这里只是为了告诉孩子在经过这么多连接之后就会死去。
换句话说:提高MaxRequestWorkers
设置将解决您的问题。