opencache的安装和使用-----以及代码不更新的问题
作者:互联网
PHP作为脚本语言, 效率是比较低下的。
现在的加速方式基本是两种:
- swoole:直接常驻内存。
- opencache:将编译后的脚本缓存起来。
原始流程:
加入cache流程
配置
官网注释,就在php.ini里面
[opcache]
; Determines if Zend OPCache is enabled
;opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP
;opcache.enable_cli=0
; The OPcache shared memory storage size.
;opcache.memory_consumption=128
; The amount of memory for interned strings in Mbytes.
;opcache.interned_strings_buffer=8
; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 1000000 are allowed.
;opcache.max_accelerated_files=10000
; The maximum percentage of "wasted" memory until a restart is scheduled.
;opcache.max_wasted_percentage=5
; When this directive is enabled, the OPcache appends the current working
; directory to the script key, thus eliminating possible collisions between
; files with the same name (basename). Disabling the directive improves
; performance, but may break existing applications.
;opcache.use_cwd=1
; When disabled, you must reset the OPcache manually or restart the
; webserver for changes to the filesystem to take effect.
;opcache.validate_timestamps=1
; How often (in seconds) to check file timestamps for changes to the shared
; memory storage allocation. ("1" means validate once per second, but only
; once per request. "0" means always validate)
;opcache.revalidate_freq=2
; Enables or disables file search in include_path optimization
;opcache.revalidate_path=0
; If disabled, all PHPDoc comments are dropped from the code to reduce the
; size of the optimized code.
;opcache.save_comments=1
; Allow file existence override (file_exists, etc.) performance feature.
;opcache.enable_file_override=0
; A bitmask, where each bit enables or disables the appropriate OPcache
; passes
;opcache.optimization_level=0xffffffff
;opcache.inherited_hack=1
;opcache.dups_fix=0
; The location of the OPcache blacklist file (wildcards allowed).
; Each OPcache blacklist file is a text file that holds the names of files
; that should not be accelerated. The file format is to add each filename
; to a new line. The filename may be a full path or just a file prefix
; (i.e., /var/www/x blacklists all the files and directories in /var/www
; that start with 'x'). Line starting with a ; are ignored (comments).
;opcache.blacklist_filename=
; Allows exclusion of large files from being cached. By default all files
; are cached.
;opcache.max_file_size=0
; Check the cache checksum each N requests.
; The default value of "0" means that the checks are disabled.
;opcache.consistency_checks=0
; How long to wait (in seconds) for a scheduled restart to begin if the cache
; is not being accessed.
;opcache.force_restart_timeout=180
; OPcache error_log file name. Empty string assumes "stderr".
;opcache.error_log=
; All OPcache errors go to the Web server log.
; By default, only fatal errors (level 0) or errors (level 1) are logged.
; You can also enable warnings (level 2), info messages (level 3) or
; debug messages (level 4).
;opcache.log_verbosity_level=1
; Preferred Shared Memory back-end. Leave empty and let the system decide.
;opcache.preferred_memory_model=
; Protect the shared memory from unexpected writing during script execution.
; Useful for internal debugging only.
;opcache.protect_memory=0
; Allows calling OPcache API functions only from PHP scripts which path is
; started from specified string. The default "" means no restriction
;opcache.restrict_api=
; Mapping base of shared memory segments (for Windows only). All the PHP
; processes have to map shared memory into the same address space. This
; directive allows to manually fix the "Unable to reattach to base address"
; errors.
;opcache.mmap_base=
; Enables and sets the second level cache directory.
; It should improve performance when SHM memory is full, at server restart or
; SHM reset. The default "" disables file based caching.
;opcache.file_cache=
; Enables or disables opcode caching in shared memory.
;opcache.file_cache_only=0
; Enables or disables checksum validation when script loaded from file cache.
;opcache.file_cache_consistency_checks=1
; Implies opcache.file_cache_only=1 for a certain process that failed to
; reattach to the shared memory (for Windows only). Explicitly enabled file
; cache is required.
;opcache.file_cache_fallback=1
; Enables or disables copying of PHP code (text segment) into HUGE PAGES.
; This should improve performance, but requires appropriate OS configuration.
;opcache.huge_code_pages=0
; Validate cached file permissions.
;opcache.validate_permission=0
; Prevent name collisions in chroot'ed environment.
;opcache.validate_root=0
; If specified, it produces opcode dumps for debugging different stages of
; optimizations.
;opcache.opt_debug_level=0
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
;curl.cainfo =
翻译一下:
[Zend Opcache]
zend_extension = opcache.so
#比较常用的配置
opcache.enable=1 #是否启用操作码缓存
opcache.enable_cli=1 #仅针对CLI环境启用操作码缓存
opcache.revalidate_freq=60 #检查文件的修改的时间周期, 定位为秒,即缓存后60秒去检查代码文件是否被修改过
opcache.fast_shutdown=1 #打开快速关闭, 一次释放全部请求变量的内存,打开这个在PHP Request Shutdown的时候回收内存的速度会提高;
opcache.error_log="" #OPcache模块的错误日志文件;
opcache.log_verbosity_level=1 #将错误信息写入到服务器的日志级别。致命(0)错误(1) 警告(2)信息(3)调试(4)
#其它不常用的配置
opcache.memory_consumption=128 #共享内存大小,单位MB
opcache.interned_strings_buffer=8 #存储临时字符串的内存大小,单位MB
opcache.max_accelerated_files=4000 #哈希表中可存储的脚本文件数量上限;
opcache.max_wasted_percentage=5 #浪费内存的上限,以百分比计;
opcache.use_cwd=1 #附加改脚本的工作目录,避免同名脚本冲突
opcache.validate_timestamps=1 #每隔revalidate_freq 设定的秒数 检查脚本是否更新;
opcache.revalidate_path=0 #如果禁用此选项,在同一个 include_path 已存在的缓存文件会被重用;
opcache.save_comments=1 #禁用后将也不会加载注释内容
opcache.enable_file_override=0 #如果启用,则在调用函数file_exists(), is_file() 以及 is_readable() 的时候, 都会检查操作码缓存;
opcache.optimization_level=0xffffffff #控制优化级别的二进制位掩码。;
opcache.inherited_hack=1 #PHP 5.3之前做的优化;
opcache.dups_fix=0 #仅作为针对 “不可重定义类”错误的一种解决方案。;
opcache.blacklist_filename="" #黑名单文件为文本文件,包含了不进行预编译优化的文件名;
opcache.max_file_size=0 #以字节为单位的缓存的文件大小上限;
opcache.consistency_checks=0 #如果是非 0 值,OPcache 将会每隔 N 次请求检查缓存校验和
opcache.force_restart_timeout=180 #如果缓存处于非激活状态,等待多少秒之后计划重启。;
opcache.preferred_memory_model="" #OPcache 首选的内存模块。可选值包括: mmap,shm, posix 以及 win32。;
opcache.protect_memory=0 #保护共享内存,以避免执行脚本时发生非预期的写入。 仅用于内部调试。;
opcache.mmap_base=null #在Windows 平台上共享内存段的基地址
- opcache.max_accelerated_files - 控制一次最多可以加载多少个PHP文件到内存。
- 你可以通过find . -type f -print | grep php | wc -l快速计算出你代码仓库里有多少个文件。
伸手党看这里:
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.file_cache=/tmp
zend_extension="opcache.so"
代码不自动更新
现象
很多人加了Opcache后发现上了代码不生效了。这个就是配置导致的了。
首先,这不是问题,理论上这不是问题,甚至在生产环境是比较好的选择。
其次,我们看看是什么配置导致的:
;opcache.validate_timestamps=1
;opcache.fast_shutdown=1
;opcache.revalidate_freq=60
- opcache.revalidate_freq - 简单的说,多久(单位是秒)检查一次你的代码缓存(opcache)是否过期。
- 0代表每一个请求都回去检查你的PHP代码
- opcache.validate_timestamps - 当这个选项开启的时候,PHP将每隔(你设置的opcache.revalidate_freq 的值)秒去检查文件的最后修改时间。
问题就在这里
; When disabled, you must reset the OPcache manually or restart the
; webserver for changes to the filesystem to take effect.
当你未开启该选项的时候,opcache.revaliate_freq的设置会被忽略,你的PHP文件将永远不会因为代码更新去检查文件修改时间。因此,如果你修改了你的代码,修改将不会生效直到你重启PHP(或者强制通过Kill -SIGUSR2)。
是的,这感觉有点痛苦并且荒唐,但是你应该去使用它,为什么呢?当你更新或者部署代码的时候新代码可能会与旧代码掺杂在一起,那运行结果就不可知了,像地狱一样不安全。
解决方案
改配置
可以通过更改 Opcache 以下两个配置选项来调整代码重载时间
opcache.revalidate_freq=0
opcache.validate_timestamps=0 。
PS:在实际生产环境中,为了尽可能达到最优性能,尽量不开启文件更新验证,因为每次验证都会重新预编译PHP代码到共享内存中。
重启 | 重载 php-fpm 进程
每次重启或重启 php-fpm 进程便会重新解析PHP脚本文件,但是重启 fpm 进程可能会导致请求中断,从而导致写入脏数据 或者 造成事务回滚等一系列异常。
重载相对于重启则平顺很多,不会导致用户请求直接中断,相对来说风险低很多,但是php-fpm 收到reload信号,便会向所有子进程发送SIGGUIT信号,同时注册一个定时器,在规定的时间之内子进程没有退出,接着在发送SIGTERM信号,结束子进程。如果在一秒之内子进程还是没结束 直接发送SIGKILL 强制杀死。
重启php-fpm
service php-fpm restart
重载php-fpm
service php-fpm reload
或 kill -USR2cat /usr/local/php/var/run/php-fpm.pid
手动清理缓存
除了上面的两种方式,还有更为稳妥一点的缓存清理,我们可以通过opcache_reset()和opcache_invalidate() 函数来刷新Opcache缓存。
-
opcache_reset() - 重置整个Opcode缓存,所有的PHP脚本将会被重新解析再预编译为Opcode。
-
opcache_invalidate() - 清除指定脚本缓存,可以传递两个参数,一个是刷新文件路径,一个是force字段, 如果 force 没有设置或者传入的是 FALSE,那么只有当脚本的修改时间 比对应Opcode的时间更新时,脚本的缓存才会失效。
需要注意的是,当PHP以PHP-FPM的方式运行的时候,opcache的缓存是无法通过php命令进行清除的,只能通过http或cgi到php-fpm进程的方式来清除缓存,我们可以编写一个对外接口,来达到清理缓存的目的。
相关实现如下(框架:laravel):
Route::any('cache-reset', function () {
//重置整个Opcode缓存
dd(opcache_reset());
});
Route::any('cache-update', function () {
//清除掉最近一次更新文件的缓存
exec('git diff --name-only HEAD~ HEAD', $output);
foreach ($output as $file) {
$path = base_path($file);
opcache_invalidate($path, true);
}
dd('刷新完成');
});
总结
通过上面的三种策略,可以实现 Opcache 缓存更新的目的,但是在流量高峰期或者大流量的服务端,每次更新缓存都是一件非常损耗资源的事情,Opcache在重建缓存时,也不会禁止其他进程读取,因此就会造成反复新建缓存,因此想要达到最佳的性能调配:
- 最好不要在高峰期清理缓存
- 高峰期不要频繁的更新代码,清理缓存,会造成重复新建缓存
- 如果需要更新,可以尝试削弱服务端权重,实现逐个更新的目的。
- 如果需要强制更新,尽量选择手动清除缓存的方式,来重建Opcache缓存,使代价最小化。
标签:缓存,代码,cache,opencache,-----,file,memory,PHP,opcache 来源: https://blog.csdn.net/happy_teemo/article/details/113420534