php编译为opcache,PHP内核 - 编译与执行 - Opcache

一、前言

一个 request 从请求之初到最终处理完成总是需要经历编译、执行两个阶段,请求结束后关于这个请求的所有数据就被擦除了,下次请求时需要经历同样的过程。

在这个过程中我们很容易发现一个问题:当多次请求同一个脚本时,需要重复经历编译的过程。只要脚本的内容没有发生变化,那么多次编译的结果实际上是相同的,这样就导致在重复的工作上花费了大量时间。 opcache 就是用来解决这个问题的,它把编译后的结果缓存下来,再次请求时不需要再重新编译,而是使用缓存的内容,直接进入执行阶段,从而大大提高了 PHP 的性能。

Opcache —— 一个用于缓存 opcodes 以提升 PHP 性能的 Zend 扩展,它的前身是 Zend Optimizer Plus (简称 O+ ),目前 Opcache 已经是 PHP 非常重要的一个组成部分,它对于 PHP 性能的提升有着非常显著的作用。

PHP 编译生成的 opcodes 指令与 Java 编译生成的字节码的角色是相同的,Java 将字节码保存到了 .class 中,而 Opcache 也可以把 opcodes 指令缓存到文件中,

从而实现跨生命周期使用,从这个角度看 PHP 与 Java 是非常相似的。

二、Opcache 工作原理

Opcache 最主要的功能是缓存 PHP 代码编译生成的 opcodes 指令,它的工作原理

如下:

(1) 开启 Opcache 之后,它将 PHP 的编译函数 zend_compile_file 替换为 persistent_compile_file(),接管 PHP 代码的编译过程,当新的请求到达时,将调用 persistent_compile_file() 进行编译。

(2) 此时 Opcache 首先检査是否有该文件的缓存,如果有则取出,然后进行一系列的验证,如果最终发现缓存可用则直接返回,进入执行流程,如果没有缓存或缓存已经失效,则重新调用系统默认的编译器进行编译,然后将编译后的结果缓存下来,供下次使用。整体的处理流程如图所示:

三、内部实现

1、初始化

Opcache是一个Zend 扩展,在 PHP 的 module_startup 阶段将调用 Zend 扩展的startup方法进行启动。

Opcache定义的startup 方法为 accel_accept(),此时 Opcache 将覆盖一些 ZendVM 的函数句柄,其中最重要的一个就是上面提到的 zend_compile_file()。

同时,该过程还会分配一个 zend_accel_shared_globals 结构,这个结构通过共享内存分,进程间共享,它保存着所有的 opcodes 缓存信息,以及一些统计数据,ZCSG() 宏操作的就是这个结构。

2、缓存的获取过程

编译一个脚本调用的是 zend_compile_file(),此时将由 Opcache 的 persistent_compile_file() 处理。

这里说下Opcache 的比较重要的两个配置:

(1)opcache.validate_timestamps:是否开启缓存有效期验证,默认值为 1,表示开启,开启之后每隔 opcache.revalidate_freg 秒检査一次文件是否更新了;如果不开启则不会检査,脚本文件修改了只能重启服务才能生效。 opcache.revalidate_freq 默认为2s。

(2)opcache.revalidate_path:验证文件路径,默认值为 0,表示关闭。默认情况下, opcodes 缓存并不是通过完整的文件路径名称进行索引的,而是通过一个根据文件名、当前所在目录、 include_path 生成的 key,因此当编译的文件实际已经不存在了但是缓存还在的时候,就会使用已经失效的缓存,如果开启这个选项,将通过完整的文件路径检索缓存,并且检查文件是否存在,而不再使用那个key。

3、缓存的生成

在 persistent_compile_file() 中我们简单介绍了缓存的查询过程,如果没有缓存或者缓存失效了,则需要重新编译并缓存结果,其中编译的过程由opcache_compile_file()完成,编译完成后调用cache_script_in_shared_memory() 进行缓存。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值