上周我们更新了几个 wordpress 站点,这些站点通过 LXD 将 Alpine Linux 作为主机(Ubuntu 20.04)中的容器运行。
更新摘要如下:
Alpine Linux v3.8 -> 3.14
PHP 5.3.6 -> 7.4.24
Wordpress 5.0.3 -> 5.7.3
问题
在这些更新之后,我们开始遇到服务器性能问题,我们发现更新后的容器使用的内存(常驻内存)是旧容器的 3 倍或更多(大约 150MB 对 50MB),这导致服务器开始更频繁地交换。
在旧版本中(使用 PHP 5.3),php
(进程)使用的内存会随着页面的处理(如预期的那样)增加,但在它完成后,它会恢复正常。换句话说,类似于:10MB
---> 95MB
---> 10MB
。
在更新的容器中,所使用的内存php
以相同的方式增加,但不会恢复到“正常”:10MB
---> 95MB
---> 95MB
。每次使用新进程时,都会发生同样的情况,通过可用子进程的数量(在本例中为每个站点 4 个)增加内存使用量。
我试过的
- 将 PHP 版本降级到
7.2.x
和7.3.x
:同样的事情 - 更新为
php 8.0.11
:同样的问题 - 使用
apache2
而不是lighttpd
(当前 php 作为 fcgi 运行):相同的行为 - 仅更新 Alpine 和 PHP 以确定 Wordpress 是否可能是原因:wordpress 不是原因
- 在没有插件的情况下运行 wordpress(以了解某些插件是否可能导致问题):没有变化
- 执行了一个简单的连接循环(纯 php):同样的事情
- 在具有不同 wordpress 站点的不同服务器中测试:相同的行为
它没有恢复内存的原因是什么?如何修复?
更新
- 我设置了一个干净的
Alpine 3.14
容器并执行了“简单循环”测试。在这种情况下,常驻内存按预期减少了。但是,一旦我使用实际的 wordpress 站点进行测试,问题仍然存在。 - 我设置了一个干净的
Ubuntu 20.04
容器并进行了相同的测试。结果与 clean 相同Alpine 3.14
。
根据这个错误报告,它并不是真正的错误,而是Zend 引擎内存管理下 PHP7+ 中的一个功能:
建议的解决方案是调用:gc_mem_caches()。如果需要,您可以使用
auto_prepend_file
和auto_append_file
指令php.ini
来执行它。但是,该解决方案对我的情况没有帮助,因此不能保证它会起作用。
由于目前没有简单的方法来改变这种行为,我找到了另一种解决内存问题的方法(它应该适用于 PHP7、PHP8):
php-cgi
,使用php-fpm
ondemand
mode 或dynamic
:/etc/php7/php-fpm.d/www.conf
:或者:
它们之间的主要区别是
ondemand
空闲时会使用更少的内存,但客户端连接时会更慢。这是我的结果的比较:
表中的值是近似值,仅用于说明目的(无论如何都不是真正的基准)。