[网安] 三: 4核服务器CPU满载问题:PHP-FPM进程数优化实战

问题复现

大量cpu满载,但是内存ok,磁盘ok。
看监控曲线,都是正常的。就是硬把cpu跑满了。

4核服务器CPU满载问题:PHP-FPM进程数优化实战

梳理一下今天的问题解决过程:

  1. 问题发现:CPU满载,load average超过50
  2. 排查发现:php-fpm进程数97个,但配置显示max_children=50
  3. 深入分析:发现有6个PHP版本同时运行,总最大进程数达490个
  4. 问题根因:4核CPU运行490个进程,上下文切换开销巨大
  5. 解决方案:降低各版本max_children参数,调整spare_servers参数
  6. 最终效果:进程数从97降到23,负载从50+降到0.16
  7. 后续监控:编写Python监控脚本

debug 问题 部分截图(就让你们看看 参考一下。)

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战
上图,是配置文件一大堆 就不截图全部了

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

成功:

文件上传中...
4核服务器CPU满载问题:PHP-FPM进程数优化实战

运维脚本:

4核服务器CPU满载问题:PHP-FPM进程数优化实战

4核服务器CPU满载问题:PHP-FPM进程数优化实战

目录

  1. 问题背景
  2. 问题现象
  3. 排查过程
  4. 根因分析
  5. 解决方案
  6. 优化效果
  7. 监控脚本
  8. 经验总结

问题背景

服务器配置:

  • CPU: Intel Xeon E5-2670 v2 @ 2.50GHz × 2(4核心)
  • 内存: 6GB
  • 系统: CentOS + 宝塔面板
  • Web服务: Apache + PHP多版本
  • 网站数量: 约70个网站

问题现象

系统状态异常

[root@ebs-159944 ~]# uptime
14:10:32 up 1:02, 2 users, load average: 52.34, 51.89, 50.25

[root@ebs-159944 ~]# top
%Cpu(s): 98.7 us, 1.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

关键指标异常:

  • CPU负载:52.34(4核CPU正常负载应小于4)
  • CPU使用率:98.7%
  • 系统几乎无响应

排查过程

1. 检查进程数量

[root@ebs-159944 ~]# ps aux | grep php-fpm | wc -l
97

2. 查看PHP-FPM配置

[root@ebs-159944 ~]# cat /www/server/php/74/etc/php-fpm.conf
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10

疑点发现: 配置显示最大50个进程,但实际运行97个

3. 深入检查PHP版本

[root@ebs-159944 ~]# ls /www/server/php/
56  70  71  72  73  74  82

[root@ebs-159944 ~]# systemctl list-units | grep php-fpm
php-fpm-56.service    loaded active running
php-fpm-70.service    loaded active running  
php-fpm-71.service    loaded active running
php-fpm-72.service    loaded active running
php-fpm-73.service    loaded active running
php-fpm-74.service    loaded active running

真相大白: 6个PHP版本同时运行!

4. 统计各版本配置

find /www/server/php -name "php-fpm.conf" -exec grep "pm.max_children" {} \;

配置汇总:

  • PHP 5.6: max_children = 80
  • PHP 7.0: max_children = 150
  • PHP 7.1: max_children = 80
  • PHP 7.2: max_children = 50
  • PHP 7.3: max_children = 80
  • PHP 7.4: max_children = 50

理论最大进程数: 80+150+80+50+80+50 = 490个进程

根因分析

CPU与进程关系

490个进程 vs 4CPU核心 = 平均每核心122个进程

问题本质

  1. 进程切换开销巨大:CPU忙于调度进程而非处理请求
  2. 资源竞争激烈:大量进程争抢少量CPU资源
  3. 响应时间延长:请求排队等待CPU调度

理论最佳配置

# 经验公式:max_children = CPU核心数 × 2~4
# 4CPU建议:32-64个总进程
# 6个版本分配:每版本6-12个进程

解决方案

1. 批量优化进程数配置

# 大幅降低各版本最大进程数
sed -i 's/pm.max_children = 150/pm.max_children = 8/' /www/server/php/70/etc/php-fpm.conf
sed -i 's/pm.max_children = 80/pm.max_children = 6/' /www/server/php/71/etc/php-fpm.conf
sed -i 's/pm.max_children = 80/pm.max_children = 6/' /www/server/php/73/etc/php-fpm.conf
sed -i 's/pm.max_children = 80/pm.max_children = 6/' /www/server/php/56/etc/php-fpm.conf
sed -i 's/pm.max_children = 50/pm.max_children = 6/' /www/server/php/72/etc/php-fpm.conf
sed -i 's/pm.max_children = 50/pm.max_children = 8/' /www/server/php/74/etc/php-fpm.conf

2. 调整spare_servers参数

# 修正spare_servers参数(必须小于max_children)
sed -i 's/pm.min_spare_servers = 5/pm.min_spare_servers = 2/' /www/server/php/56/etc/php-fpm.conf
sed -i 's/pm.max_spare_servers = 20/pm.max_spare_servers = 4/' /www/server/php/56/etc/php-fpm.conf
sed -i 's/pm.start_servers = 5/pm.start_servers = 2/' /www/server/php/56/etc/php-fpm.conf

3. 重启所有PHP服务

systemctl restart php-fpm-56 php-fpm-70 php-fpm-71 php-fpm-72 php-fpm-73 php-fpm-74

4. 处理配置错误

常见错误:

ALERT: [pool www] pm.min_spare_servers(5) and pm.max_spare_servers(8) cannot be greater than pm.max_children(6)

解决方法: 确保参数关系正确

pm.min_spare_servers < pm.max_spare_servers < pm.max_children

优化效果

对比数据

指标 优化前 优化后 改善幅度
PHP-FPM进程数 97个 23个 ↓76%
CPU负载(1分钟) 52.34 0.16 ↓99.7%
理论最大进程数 490个 40个 ↓92%
系统响应 几乎无响应 正常 完全恢复

验证命令

[root@ebs-159944 ~]# ps aux | grep php-fpm | wc -l
23

[root@ebs-159944 ~]# uptime
14:30:13 up 1:22, 2 users, load average: 0.16, 6.44, 26.44

监控脚本

为防止问题复发,编写Python监控脚本:

#!/usr/bin/env python3
# 监控脚本:/www/wwwroot/bobomonitor/server_monitor.py

class ServerMonitor:
    def __init__(self):
        self.load_threshold = 2.0           # CPU负载告警阈值
        self.phpfpm_threshold = 60          # PHP-FPM进程数告警阈值  
        self.memory_threshold = 85          # 内存使用率告警阈值(%)
        self.log_file = "/www/wwwroot/bobomonitor/server_monitor.log"

    def check_and_alert(self):
        load_avg = self.get_load_average()
        phpfpm_count = self.get_phpfpm_count()
        memory_usage = self.get_memory_usage()

        if load_avg > self.load_threshold:
            self.send_alert(f"CPU负载过高: {load_avg}")
        if phpfmp_count > self.phpfpm_threshold:
            self.send_alert(f"PHP-FPM进程过多: {phpfpm_count}")

宝塔计划任务设置

# 任务类型:Shell脚本
# 执行周期:每5分钟  
# 脚本内容:
cd /www/wwwroot/bobomonitor && /usr/bin/python3 server_monitor.py

经验总结

1. PHP-FPM参数最佳实践

# 4CPU服务器建议配置
pm.max_children = CPU核心数 × 2~3
pm.start_servers = max_children / 4
pm.min_spare_servers = start_servers
pm.max_spare_servers = max_children / 2

2. 多版本PHP优化策略

  • 版本整合:关闭不使用的PHP版本
  • 按需分配:主要版本分配更多进程
  • 总量控制:所有版本总进程数不超过CPU核心数×16

3. 监控告警机制

  • 实时监控:每5分钟检查关键指标
  • 提前预警:设置合理的告警阈值
  • 自动化处理:结合脚本实现自动重启等操作

4. 性能优化要点

  1. 避免过度配置:根据实际访问量调整参数
  2. 定期检查:监控长期运行状态
  3. 版本管理:及时清理无用的PHP版本
  4. 负载均衡:考虑使用CDN分散请求压力

通过这次优化,不仅解决了CPU满载问题,还建立了完整的监控体系,为服务器稳定运行提供了保障。


关键词: PHP-FPM优化、CPU负载过高、进程数控制、服务器性能调优、宝塔面板

本作品采用《CC 协议》,转载必须注明作者和本文链接
• 15年技术深耕:理论扎实 + 实战丰富,教学经验让复杂技术变简单 • 8年企业历练:不仅懂技术,更懂业务落地与项目实操 • 全栈服务力:技术培训 | 软件定制开发 | AI智能化升级 关注「上海PHP自学中心」获取实战干货
wangchunbo
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
司机 @ 某医疗行业
文章
315
粉丝
353
喜欢
565
收藏
1136
排名:61
访问:12.6 万
私信
所有博文
社区赞助商