最近几周,我们在部署代码时遇到了一种负面现象:服务器有时会在几分钟内失去响应。
下面是发生这种情况时服务器上负载的一个例子:

我能找到的唯一相关日志来自/var/log/php7.2-fpm.log,有时(但并非总是如此)我看到这样的条目(注意:这是来自与上面显示的图像不同的事件,但也会发生相同的情况):
[22-Mar-2019 15:33:50] WARNING: [pool api] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 231 total children
[22-Mar-2019 15:33:52] WARNING: [pool api] server reached pm.max_children setting (250), consider raising it
[22-Mar-2019 15:34:05] WARNING: [pool app] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 47 idle, and 104 total children发生的事情是,我们对这个服务器进行了部署:
git status --porcelaingit pull origin master更新文件opcache_reset()的端点在进行了一些实验之后,我可以将负载问题减少到以下几个方面:opcache_reset()
一旦我执行了这个调用(独立于任何先前或以后的部署步骤,当我只调用这个端点时,这也是孤立的),系统负载就有可能突然猛增。
如果发生这种情况,并且负载“太高”(我会说,根据经验> 200左右),系统会在几秒钟或几分钟内变得没有响应,这取决于每件事情需要多长时间才能平静下来。
规格:
PHP配置:
start_servers直接汇总到320个php过程(也通过ps auxw|grep -i fpm|grep -v grep |wc -l确认)max_children总数将在870左右。也许这里的总数太高了,目的是为了应对个别虚拟主机上的突发事件,而这些虚拟主机有时也会出现。
使用htop,系统通常如下所示:

通常情况下,负载很低,除非我们有这个尖峰,它们都与opcache重置有关(我最近才发现):

我知道重新设置缓存,现在所有进程都必须重新填充它,这是CPU消耗。
但我不明白的是:
下面是部署之前的opcache_get_status(false)输出:
{
"opcache_enabled": true,
"cache_full": false,
"restart_pending": false,
"restart_in_progress": false,
"memory_usage": {
"used_memory": 67353640,
"free_memory": 66864088,
"wasted_memory": 0,
"current_wasted_percentage": 0
},
"interned_strings_usage": {
"buffer_size": 8388608,
"used_memory": 5215176,
"free_memory": 3173432,
"number_of_strings": 89109
},
"opcache_statistics": {
"num_cached_scripts": 2873,
"num_cached_keys": 5063,
"max_cached_keys": 7963,
"hits": 633581523,
"start_time": 1553172771,
"last_restart_time": 1553248200,
"oom_restarts": 0,
"hash_restarts": 0,
"manual_restarts": 6,
"misses": 9512,
"blacklist_misses": 0,
"blacklist_miss_ratio": 0,
"opcache_hit_rate": 99.9984987161316
}
}在此之后:
{
"opcache_enabled": true,
"cache_full": false,
"restart_pending": false,
"restart_in_progress": false,
"memory_usage": {
"used_memory": 57745856,
"free_memory": 76471872,
"wasted_memory": 0,
"current_wasted_percentage": 0
},
"interned_strings_usage": {
"buffer_size": 8388608,
"used_memory": 4337168,
"free_memory": 4051440,
"number_of_strings": 75163
},
"opcache_statistics": {
"num_cached_scripts": 2244,
"num_cached_keys": 3925,
"max_cached_keys": 7963,
"hits": 5893926,
"start_time": 1553172771,
"last_restart_time": 1553265235,
"oom_restarts": 0,
"hash_restarts": 0,
"manual_restarts": 7,
"misses": 4962,
"blacklist_misses": 0,
"blacklist_miss_ratio": 0,
"opcache_hit_rate": 99.91588245106536
}
}我观察到的其他事情:
究竟是什么原因造成了这些负荷峰值?我怎么才能避开他们?
接受答案后的
基本上,不调用opcache_reset并将大部分opcache设置自定义恢复到缺省值(即不强制设置它们)就可以修复它。
这一步是我多年来部署过程中的一部分。我试图找出最初的原因,据我所见,它与类引用尚未加载/刷新的新代码时的部署问题有关。
事后看来,我甚至不确定这是真正的问题,但我们到了。
发布于 2019-03-25 13:31:10
默认情况下,PHP检查文件时间戳以使opcache条目无效。这是可以关闭的,这是我能想到的使用opcache_reset()的唯一场景。当然,这也会导致你遇到的问题。
我建议回到默认值:
opcache.validate_timestamps = 1
opcache.revalidate_freq = 2
opcache.revalidate_path = 0https://serverfault.com/questions/959520
复制相似问题