php的opcache

一、opcache的原理

1、Opcache是什么?

Opcache是一种通过将解析的PHP脚本预编译的字节码(Operate Code)存放在共享内存中来避免每次加载和解析PHP脚本的开销,解析器可以直接从共享内存读取已经缓存的字节码(Operate Code),从而大大提高PHP的执行效率。

2、什么是Operate Code?

当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode)。Opcode cache的目地是避免重复编译,减少CPU和内存开销。如果动态内容的性能瓶颈不在于CPU和内存,而在于I/O操作,比如数据库查询带来的磁盘I/O开销,那么opcode cache的性能提升是非常有限的。但是既然opcode cache能带来CPU和内存开销的降低,这总归是好事。现代操作码缓存器(Optimizer+,APC2.0+,其他)使用共享内存进行存储,并且可以直接从中执行文件,而不用在执行前“反序列化”代码。这将带来显着的性能加速,通常特别是高流量和高并发量时降低了整体服务器的内存消耗,而且很少有缺点。

3、为什么要使用Opcode缓存?

这得从PHP代码的生命周期说起,请求PHP脚本时,会经过五个步骤,如下图所示:
在这里插入图片描述
Zend引擎必须从文件系统读取文件、扫描其词典和表达式、解析文件、创建要执行的计算机代码(称为Opcode),最后执行Opcode。每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重行生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快,启用Opcode缓存之后的流程图如下所示:
在这里插入图片描述

因此使用了Operate Code缓存之后,PHP代码会直接获取opcode后直接执行,中间的三个步骤会省略掉因此会大幅提高PHP代码执行效率

注:PHP 5.5.0 及后续版本中已经绑定了 OPcache 扩展。 对于 PHP 5.2,5.3 和 5.4 版本可以使用 » PECL 扩展中的 OPcache 库

二、opcache的使用

#在php.ini中开启扩展

[opcache]
zend_extension=opcache.so

;启用操作码缓存。如果禁用此选项,则不会优化和缓存代码
opcache.enable=1

;仅针对 CLI 版本的 PHP 启用操作码缓存。 通常被用来测试和调试
opcache.enable_cli=1

;OPcache 的共享内存大小,以兆字节为单位
opcache.memory_consumption=256

;用来存储预留字符串的内存大小,以兆字节为单位。 PHP 5.3.0 之前的版本会忽略此配置指令
opcache.interned_strings_buffer=16

;OPcache 哈希表中可存储的脚本文件数量上限。设置值取值范围最小值是 200,最大值在 PHP 5.5.6 之前是 100000,PHP 5.5.6 及之后是 1000000
opcache.max_accelerated_files=1000000

;如果启用,那么 OPcache 会每隔 opcache.revalidate_freq 设定的秒数 检查脚本是否更新
opcache.validate_timestamps=1

;检查脚本时间戳是否有更新的周期,以秒为单位。 设置为 0 会导致针对每个请求, OPcache 都会检查脚本更新。如果 opcache.validate_timestamps 配置指令设置为禁用,那么此设置项将会被忽略
opcache.revalidate_freq=60

;如果启用,则会使用快速停止续发事件。 所谓快速停止续发事件是指依赖 Zend 引擎的内存管理模块 一次释放全部请求变量的内存,而不是依次释放每一个已分配的内存块。从 PHP 7.2.0 开始,此配置指令被移除。 快速停止的续发事件的处理已经集成到 PHP 中, 只要有可能,PHP 会自动处理这些续发事件
opcache.fast_shutdown=1

尾声

副作用:
使用了opcache时,如果没有设置检查脚本是否更新或N秒检查一次。则会造成代码不及时。

解决办法:
1.平滑重启 php-fpm

#平滑重启的方式就类似下面这样,通过部署钩子实现
cd /www/myproject
git pull origin master
kill -USR2 php-fpm主进程

2.通过 opcache_reset () 函数

#使用 opcache_reset () 函数需要注意的问题就是在 cli 命令行下执行此函数并不能清理 php-fpm 下生成的缓存字节码,所以可以通过一种曲线救国的方式
curl http://example.com/op.php
#这个 op.php 文件里面就专门执行 opcache_reset () 函数,但是这种方式总感觉有点怪怪的

3.第三方库 cachetool => https://github.com/gordalina/cachetool

生产环境中:
建议将validate_timestamps关闭,即不自动检测文件是否更新。则能极大的提高服务器性能。
开发环境中:
建议将validate_timestamps=1 revalidate_freq=0,则会每个请求都会检测文件是否更新

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值