参考:记一次laravel项目因opcache导致的include过慢问题 - PHP面试网
问题表现 php-fpm-slow.log 大量如下日志:
script_filename = /data/nginx/webroot/app-20200611-160330-feb90625/public/index. php [0x00007fc41e61da20] Composer\Autoload\includeFile() /data/nginx/webroot/app-202 00611-160330-feb90625/vendor/composer/ClassLoader.php:322 [0x00007fc41e61d980] loadClass() unknown:0 [0x00007fc41e61d920] spl_autoload_call() unknown:0 [0x00007ffdb62f6820] ???() /data/nginx/webroot/app-20200611-160330-feb90625/vend or/laravel/lumen-framework/src/Exceptions/Handler.php:108 [0x00007fc41e61d630] render() /data/nginx/webroot/app-20200611-160330-feb90625/a pp/Exceptions/Handler.php:51 [0x00007fc41e61d5b0] render() /data/nginx/webroot/app-20200611-160330-feb90625/v endor/laravel/lumen-framework/src/Concerns/RegistersExceptionHandlers.php:105 [0x00007fc41e61d4b0] sendExceptionToHandler() /data/nginx/webroot/app-20200611-1 60330-feb90625/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php:17 3 [0x00007fc41e61d1c0] dispatch() /data/nginx/webroot/app-20200611-160330-feb90625 /vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php:108 [0x00007fc41e61d0c0] run() /data/nginx/webroot/app-20200611-160330-feb90625/publ ic/index.php:28 [11-Jun-2020 16:04:24] [pool www] pid 25856
查看源代码,发现就是include过慢???
public function loadClass($class) { if ($file = $this->findFile($class)) { includeFile($file); return true; } } function includeFile($file) { include $file; }
怀疑是IO的问题,查看IO的使用情况参考:linux中如何查看系统io使用情况 - PHP面试网
sar -b -f /var/log/sa11 06:20:01 PM tps rtps wtps bread/s bwrtn/s 08:50:01 PM 3.44 0.00 3.44 0.01 306.01 09:00:03 PM 5.35 0.40 4.95 4.73 517.89 09:10:01 PM 23.73 15.86 7.87 207.76 799.36 09:20:03 PM 24.03 15.24 8.79 194.55 1147.58 09:30:01 PM 120.86 117.67 3.19 19941.43 164.30 09:40:01 PM 16.58 12.96 3.62 277.86 362.99 09:50:01 PM 5.43 2.55 2.88 1786.32 380.44
发现9:30左右bread/s 非常大,怀疑由于jenkins上线过多,而且没有重新reload php-fpm导致 opcache 内存或者缓存文件数达到上线导致的include慢
于是重启 php-fpm 发现状态恢复正常。
我们再打开 php.ini 的opcache.error_log 观察后面是否会继续出现这种情况。
opcache.error_log = /data/nginx/logs/php_opcache_error.log
[opcache] ;执行OPcache目录 zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/opcache.so ; OPcache的共享内存大小,以兆字节为单位。总共能够存储多少预编译的PHP代码(单位:MB) opcache.memory_consumption=128 ;用来存储字符串的内存大小(单位:MB) opcache.interned_strings_buffer=8 ;最大缓存的文件数目200-100000 opcache.max_accelerated_files=4000 ; 检查脚本时间戳是否有更新的周期,以秒为单位。设置为0会导致针对每个请求,OPcache 都会检查脚本更新 opcache.revalidate_freq=60 ; 打开快速关闭,打开这个在PHP Request Shutdown的时候会收内存的速度会提高. opcache.fast_shutdown=1 ; 如果禁用,脚本文件中的注释内容将不会被包含到操作码缓存文件,这样可以有效减小优化后的文件体积,禁用此配置指令可能会导致一些依赖注释或注解的应用或框架无法正常工作,比如:Doctrine,Zend Framework2等. ; 推荐0 opcache.save_comments=0 ;支持cli模式 opcache.enable_cli=1
<?php // 查看 OPcache 缓存使用状况 var_dump(opcache_get_status()); // 释放所有 OPcache 缓存 opcache_reset();
警告:这篇文章反复提到的监视统计信息 opcache_get_status(false)
。因为 Opcache 为每个 SAPI 使用唯一的共享内存池,所以您无法从控制台访问 Web 服务器统计信息。该调用必须通过 Apache 或 PHP-FPM 进行。