本文目录导读:

- 排查“为什么改了代码不生效”(OPcache 问题)
- 排查“内存泄漏”或“CPU 飙升”(不中断请求)
- 排查“配置修改”问题(php.ini 或 php-fpm.conf)
- 排查“线上死循环”且无法用 kill 解决
- 排查“外部连接”问题(Redis/MySQL 连接占满)
- 核心指令速查表
在 PHP 开发或运维中,“不重启排查” 通常指的是:在不重启 PHP-FPM 或 Apache(不中断服务)的前提下,定位问题、修改配置或加载代码。
根据你遇到的具体情况(是线上故障、代码 Bug 还是配置问题),有以下几种不用重启的排查和解决方法:
排查“为什么改了代码不生效”(OPcache 问题)
如果你改了 PHP 代码,但页面没变化,通常是因为 OPcache(PHP 操作码缓存)缓存了旧代码。
- 排查方法:通过
phpinfo()查看opcache.validate_timestamps是否开启。 - 不重启的解决方案:
- 方案 A(推荐):如果你有命令行权限,执行
php -r "opcache_reset();"(需要走 FPM 的 CLI 时可能无效)或使用管理工具(如cachetool)执行cachetool opcache:reset。 - 方案 B(触发重新编译):在线上直接
touch(更新文件修改时间)对应的 PHP 文件,只要validate_timestamps开启且revalidate_freq不为 0,文件修改时间变化后,下一次请求会自动重新编译。
- 方案 A(推荐):如果你有命令行权限,执行
排查“内存泄漏”或“CPU 飙升”(不中断请求)
如果进程卡死或内存溢出,你不能直接 kill 掉所有 worker(会中断用户请求)。
- 排查方法(不重启):
- 查看当前活跃请求:执行
strace -p <PID>查看该进程正在执行什么系统调用(是否有死循环、卡在 IO)。 - 查看实时日志:执行
tail -f /var/log/php-fpm.log看是否有Max execution time或Segfault错误。 - 检查连接数:执行
netstat -anp | grep :9000看谁占着连接不释放。
- 查看当前活跃请求:执行
- 不重启的解决方案:
- 优雅重载(本质是平滑重启,但对业务无影响):执行
kill -USR2 <master_pid>(针对 PHP-FPM,注意区分:USR1 是重载日志,USR2 是重载 worker),这不会中断正在处理的请求,旧的 worker 处理完当前请求后才退出。 - 慢日志排查:如果还没到重启的地步,直接打开
request_slowlog_timeout,通过慢日志(slow.log)定位卡住的代码行。
- 优雅重载(本质是平滑重启,但对业务无影响):执行
排查“配置修改”问题(php.ini 或 php-fpm.conf)
你改了 php.ini 想改 memory_limit,但又不想重启 FPM。
- 不重启的解决方案(PHP 5.3+ / PHP 7+):
ini_set()运行时修改:如果是业务代码需要临时调大内存,直接在代码开头写ini_set('memory_limit', '512M');,这不需要重启,且立即生效。- PHP-FPM 池配置(
php_value):如果你修改的是php-fpm.conf里的php_value[memory_limit],只需执行kill -USR2 <master_pid>重载配置即可,不必完全 kill 进程。 - 重要提醒:
PHP_INI_SYSTEM级别的配置(如disable_functions)无法在运行时修改,这种情况下必须重启(或重载让 FPM 重新读取 ini)。
排查“线上死循环”且无法用 kill 解决
如果你怀疑某段代码导致 CPU 100%,但找不到 PID 对应的业务(因为 PHP-FPM 是共享进程)。
- 不重启的解决方案:
- 临时修改
max_execution_time:如果你能通过ini_set或临时修改.user.ini文件,将该时间调小(如 5 秒),让卡死的请求自动超时释放,无需手动 kill 进程。 runkit或uopz扩展(极少用):如果安装了扩展,可以在运行时uopz_unset_return替换函数逻辑(但生产环境一般不推荐装这种扩展)。
- 临时修改
排查“外部连接”问题(Redis/MySQL 连接占满)
- 不重启的解决方案:直接用
telnet或redis-cli -p 6379 client list查看 PHP 进程占用的连接,如果是连接池问题,可以通过执行kill -USR1 <fpm_master_pid>重新打开日志文件,而不是重启服务,如果是连不上外连,用ss -antp | grep php-fpm查看 TIME_WAIT 状态。
核心指令速查表
| 目的 | 命令/操作 | 是否需要完全重启 |
|---|---|---|
| 清 OPcache 缓存 | php -r 'opcache_reset();' 或 Touch 文件 |
否 |
| 加载新配置(php.ini) | kill -USR2 <master_pid>(优雅重载) |
否(平滑过渡) |
| 关闭慢请求(超时) | 修改 .user.ini 中的 max_execution_time |
否(有效期延后) |
| 查看当前运行状态 | php-fpm -t(语法检查)+ tail -f /var/log/php-fpm.log |
否 |
| 必须重启的情况 | 修改了 PHP_INI_SYSTEM 常量(如 disable_functions) |
是(必须重启) |
⚠️ 特别提醒:
如果你使用的是 Apache + mod_php,修改 php.ini 后必须重启 Apache(或 apachectl graceful - 优雅重启),如果是 Nginx + PHP-FPM,使用 USR2 重载即可。
如果只是单纯“不想影响正在下载大文件的用户”,请务必使用 kill -USR2 而不是 kill -USR1(USR1 只重载日志,不重载配置)。