我们为客户提供了一个 Dockerized 环境,以便每个客户都有自己的容器来托管自己的网站。每个容器通常在映像上运行,php:7
因此我们谈论的是Apache 2.4
使用mpm_prefork
。每个容器的内存限制为 256Mb。
现在,如果任何容器因某种原因受到攻击,使用默认的 Apache 设置,它会生成大量子进程,从而消耗整个机器的 RAM。发生这种情况是因为,显然,子进程的总内存使用量不计入限制。
我想完全阻止 Apache 生成子进程。因此,如果容器被黑客入侵,它将达到其内存限制并被 Docker 杀死。
我尝试过:
StartServers 1
MinSpareServers 1
MaxSpareServers 1
ServerLimit 1
MaxClients 1
MaxRequestsPerChild 4000
但是性能很差,包含多个 CSS/脚本资产的基本 Drupal 站点的加载时间长达近 60 秒。
是否可以强制 Apache 仅使用一个进程并至少保持一定的性能?网站很小,流量也不大,所以我们不太在意,但网站至少应该对单个用户快速加载。
答案1
您需要将这些限制从 1 增加到稍高一些的值,但可能要低于默认值。将它们设置为 1 基本上意味着您一次只能服务一个连接,这就是您看到糟糕的性能的原因。浏览器将尝试发出多个同时连接,以便获取基本页面以及其中链接的任何 CSS、Javascript 等。
答案2
但表演糟糕的
不完全是!!
您确实意识到 prefork MPM 旨在为每个请求生成子进程,并且每个子进程一次只能处理一个请求。参见如何选择使用哪个 Apache MPM?
通过限制一会发生以下情况:浏览器将尝试加载您的糟糕网页的 HTML。一旦成功,它将看到该页面依赖于许多外部 css 文件、图像和脚本资源。然后它将发送许多并行请求来加载这些资源。这些 apache 设置不会同时处理这些资源,而是仅允许 apache 能够一个接一个地、顺序地而不是同时地发送这些资源。这需要永远!
您不希望网络服务器只能勉强支持一个并发网站访问者...请调整这些设置。
考虑在您的 Docker 之前放置一个缓存反向代理服务器,以减少转发到每个 Docker 容器的命中次数,并将设置调整为更合理的设置,以使每个 Docker 容器的响应更快。