我们正在使用可以保持连接很长时间(可能是数周)的 WebSocket。
Apache 2.4.41 w/MPMEvent 有时会决定停止某个进程(例如 1:当负载下降时,2:当用户重新加载配置时,3:当 logrotate 在旋转日志后重新加载配置时 - Ubuntu 默认)。当某个进程停止时,它似乎永远不会在需要时重新启动,即使配置没有更改(同一代,未使用重新加载配置)。
websocket 连接阻止了进程停止,我们可以在 /server-status 中看到连接,线程标记为 G,表示正常完成。
我们遇到过这样一种情况:8 个进程已满,并且‘记分牌已满’,而其余 8 个进程处于‘停止’状态,并且有线程以‘G’优雅地完成。
问题 1:一旦 apache 决定停止某个进程(因为负载下降,并且不再需要该进程作为 pr )MinSpareThreads
,它是否就无法改变对该进程的想法并让该进程再次接受连接?如果我们的进程卡住的唯一原因是它们是老一代(由于 apache 重新加载),那么一个很好的解决方案就是删除 logrotate。根据我的测试,这是真的,Apache 开始接受与“正在停止”的进程的连接(但希望得到确认)。
问题 2:是否可以添加超时,以便当 Apache 需要启动新进程(即服务器)但因serverLimit
已到达而无法启动时,它会强制终止处于停止状态但因打开连接而等待的进程。从而在需要时清理空间并强制关闭连接。
我应该注意到,我们发现了设置优雅关机超时,但在发现这一点之后优雅停止很明显,这个超时是指正常停止整个 Apache 服务器,而不是停止某个进程(根据文档,又名服务器)。
我知道可能的解决方案是不使用 logrotate(这会导致所有进程每晚都停止),并更改我们的 websocket 以频繁重新连接。后者在我们的案例中并不容易,前者无法解决负载波动导致进程停止的问题。
我们的 mpm_event 配置如下所示:
<IfModule mpm_event_module>
StartServers 3
ServerLimit 16
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>