我正在准备一台新服务器 (v5) 来替换我目前在生产中的服务器 (v4)。这些机器运行 Ubuntu。v5 服务器在 mpm_event 模式下具有 PHP-FPM 8.2 和 Apache 2.4.52。我记得在设置 v4 机器时,默认的 apache/php conf 文件不太适合生产环境,因为它们没有生成足够的服务器/进程。我想优化 apache 和 php-fpm conf 文件以产生足够的进程来处理流量,但又不会太多以至于耗尽 RAM。如果我的服务器收到太多请求,我宁愿它丢弃请求,也不愿因为它将 RAM 分页到文件系统上而开始抖动。
我记得当 PHP 进程不足时,PHP-FPM 日志中会出现错误:
[22-Jan-2019 09:15:30] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 45 total children
[22-Jan-2019 09:15:31] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 47 total children
[22-Jan-2019 09:15:32] WARNING: [pool www] server reached pm.max_children setting (48), consider raising it
我最终对 PHP-FPM 做了一些惊慌失措的调整閣下網站文件,但这次我想采用更有条理的方法。特别是,我想配置 apache 和 php 以根据机器中的 RAM 数量合理地生成尽可能多的进程。该free
命令在 v5 服务器上显示大约 8GB:
$ free -m
total used free shared buff/cache available
Mem: 7930 274 7112 5 543 7408
Swap: 0 0 0
MySQL 在单独的机器上运行,因此我认为将机器配置为使用几乎所有的 RAM 用于 Apache 和 PHP(这台服务器实际上所做的就是运行这些 RAM),并为系统进程留下大约 1GB 的内存是合理的。
问题 1:是否可以合理地假设我可以使用 6930MB 的 RAM 来运行 PHP 和 Apache 进程,而剩下的 1GB 就足以满足系统工作?
我知道有很多变数,但我认为可以合理地假设我需要大致每个 Apache 进程对应一个 PHP 进程。既然如此,我可以假设N = apache_proc_count = php_proc_count
这些公式可以指导我的配置:
(mem_per_apache_proc x N) + (mem_per_php_proc x N) = (total_ram - 1GB)
(mem_per_apache_proc + mem_per_php_proc) x N = 6930MB
N = 6930 / (mem_per_apache_proc + mem_per_php_proc)
Q2:上述公式对于决定要生成的最大 apache/php 进程数是否合理?
最后,我很难确定每个 apache 和 php 进程需要多少 RAM。例如,对于 PHP 进程,我为我的工作站启动了一个 apache bench 命令,以向 v5 服务器发出并发请求,我尝试了以下ps
命令:
$ ps -C php-fpm8.2 -o "uname,ppid,pid,%cpu,pmem,rss,command,comm"
USER PPID PID %CPU %MEM RSS COMMAND COMMAND
root 1 832 0.0 0.4 34912 php-fpm: master process (/e php-fpm8.2
www-data 832 986 0.0 0.2 23296 php-fpm: pool www php-fpm8.2
www-data 832 987 0.0 0.2 22468 php-fpm: pool www php-fpm8.2
根据 ps 手册页:
rss RSS 驻留集大小,任务已使用的非交换物理内存(以千字节为单位)。(别名 rssize、rsz)。
我注意到 PHP 池进程使用很多比 v4 服务器上的 PHP 进程(约 75.1MB)占用的 RAM 更少(仅约 22.8MB)。
我也在pmap
我的 v5 服务器上运行了这个命令,得到了一个完全不同的数字:
$ sudo pmap -x 986 | grep total
total kB 258756 23464 15384
这些列分别是、Kbytes
和RSS
。Dirty
我注意到 RSS 值非常接近ps
上述命令返回的 RSS 值。
最后,我尝试了这个 PHP 命令,它报告了全部内存使用情况:
$ php -r 'sleep(60);var_dump(number_format(memory_get_peak_usage(TRUE)));'
string(9) "2,097,152"
我注意到 2097152 字节的输出与上面的 ps 命令有很大不同,该命令报告此过程的 RSS 为 32416KB。
我意识到这里涉及一些复杂的问题:共享内存等,但我不需要针对单个进程的精确答案。我只需要知道这些进程平均需要多少 RAM。我的第三个问题是问题 3:如何才能合理准确地了解平均 PHP 或 Apache 进程将消耗多少 RAM?
最后,我想对 apache conf 和 php-fpm conf 进行调整。以下是 mpm_event.conf 中的设置:
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
Q4:我是否应该简单地将 MaxRequestWorkers 设置为上面计算的值N
?或者是否建议进行其他更改?
以下是 PHP-FPM 文件 www.conf 的内容:
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Q5:我应该更改其中哪些,以便 PHP 合理地产生尽可能多的进程?
答案1
PHP 进程的内存使用量完全取决于 PHP 解释器执行的代码。包含数十个插件的完整 Drupal 安装比单个 PHP 脚本占用更多的内存。
确定某些数字的唯一实用方法是运行负载测试并在测试期间测量内存使用情况。