PHP 怎么不重启排查

wen PHP项目 2

本文目录导读:

PHP 怎么不重启排查

  1. 排查“为什么改了代码不生效”(OPcache 问题)
  2. 排查“内存泄漏”或“CPU 飙升”(不中断请求)
  3. 排查“配置修改”问题(php.ini 或 php-fpm.conf)
  4. 排查“线上死循环”且无法用 kill 解决
  5. 排查“外部连接”问题(Redis/MySQL 连接占满)
  6. 核心指令速查表

在 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,文件修改时间变化后,下一次请求会自动重新编译。

排查“内存泄漏”或“CPU 飙升”(不中断请求)

如果进程卡死或内存溢出,你不能直接 kill 掉所有 worker(会中断用户请求)。

  • 排查方法(不重启)
    • 查看当前活跃请求:执行 strace -p <PID> 查看该进程正在执行什么系统调用(是否有死循环、卡在 IO)。
    • 查看实时日志:执行 tail -f /var/log/php-fpm.log 看是否有 Max execution timeSegfault 错误。
    • 检查连接数:执行 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 进程
    • runkituopz 扩展(极少用):如果安装了扩展,可以在运行时 uopz_unset_return 替换函数逻辑(但生产环境一般不推荐装这种扩展)。

排查“外部连接”问题(Redis/MySQL 连接占满)

  • 不重启的解决方案:直接用 telnetredis-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 只重载日志,不重载配置)。

抱歉,评论功能暂时关闭!