Opcache实战

简述

字节码缓存不是PHP的新特性,有很多独立的第三方扩展实现了字节码缓存,例如APC,eAccelerator等,从PHP5.5开始内置了字节码缓存功能,名为Zend Opcache
开启字节码缓存之后,PHP解释器不用每次都读取,解析,编译PHP代码,直接从共享内存中读取opcode(字节码),极大地提升应用性能

环境

  • Ubuntu 20.04.5 LTS
  • PHP 8.2.5
  • Nginx 1.18.0
  • composer 2.5.5
  • laravel v10.8.0
  • phpfpm配置
pm = dynamic
pm.max_children = 200
pm.start_servers = 50
pm.min_spare_servers = 50
pm.max_spare_servers = 100
;pm.max_spawn_rate = 32
;pm.process_idle_timeout = 10s;
;pm.max_requests = 500

安装php8.2

# 添加PHP8.2 PPA源
# add-apt-repository ppa:ondrej/php
# apt-get -y install php8.2 
# apt-get -y install php8.2-fpm  
# apt-get -y install php8.2-opcache 
# apt-get -y install php8.2-dom 
# apt-get -y install php8.2-curl

安装laravel

$ composer create-project laravel/laravel example-app
<?php
  
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PhotoController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
            // 引入的文件总数 469个
            `echo` "Hello World!";
            die;
    }
}

第一次压测 没开Opcache

这里用的压测工具: https://github.com/link1st/go-stress-testing

# ./go-stress-testing-linux -c 50 -n 6 -u http://192.168.6.32/photos/

 开始启动  并发数:50 请求数:6 请求参数: 
request:
 form:http 
 url:http://192.168.6.32/photos/ 
 method:GET 
 headers:map[Content-Type:application/x-www-form-urlencoded; charset=utf-8] 
 data: 
 verify:statusCode 
 timeout:30s 
 debug:false 
 http2.0:false 
 keepalive:false 
 maxCon:1 


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────
 耗时│ 并发数│ 成功数│ 失败数│   qps  │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 状态码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────
   1s│     34│     34│      0│   57.96│  990.05│  682.80│  862.72│     408│     407│200:34
   2s│     50│     99│      0│   57.01│ 1173.19│  682.80│  877.02│   1,188│     593│200:99
   3s│     50│    154│      0│   58.88│ 1173.19│  647.19│  849.23│   1,848│     615│200:154
   4s│     50│    210│      0│   59.45│ 1173.19│  647.19│  840.99│   2,520│     629│200:210
   5s│     50│    300│      0│   61.91│ 1173.19│  418.52│  807.67│   3,600│     727│200:300


*************************  结果 stat  ****************************
处理协程数量: 50
请求总数(并发数*请求数 -c * -n): 300 总请求时间: 4.946 秒 successNum: 300 failureNum: 0
tp90: 963.000
tp95: 1020.000
tp99: 1134.000
*************************  结果 end   ****************************

推荐配置

opcache.enable = 1
设置为 1,开启 Opcache 功能。

opcache.validate_timestamps=0
设置为1表示将根据您的 opcache.revalidate_freq 值检查文件时间戳判断文件有没有更改
生产环境中配置为0,生产环境不需要验证文件变动,每次更新部署代码的时候,重启fpm即可,systemctl restart php8.2-fpm.service或者kill -SIGUSR2 pid
顺便解决了上代码的时候文件新旧混合的问题,就是说你要上100个文件,上传完之前,总会出现50个新文件,50个旧文件的时刻,可能会发生一些不愉快的结果
其实开发环境也不太需要用到opcache,所以这个值无脑设置为0

opcache.revalidate_freq=0
当validate_timestamps=1时这个设置才有用
opcache缓存时间,设置为0表示每次都要检查校验文件时间戳判断文件有没有改变,这里会用到系统调用stat
当validate_timestamps=0时,这个值不需要设置

opcache.memory_consumption=128
可以使用函数 opcache_get_status() 来了解 opcache 消耗了多少内存以及是否需要增加数量
也可以在phpinfo()查看缓存详情

image.png

默认值64MB,这里设置为128MB

opcache.interned_strings_buffer=16
在php-fpm进程组之间使用16MB共享内存来存储公共字符串,比如很几百个类都有个字符串变量值为hello world,启用这个选项后,只需要在共享内存里面存一次hello world,变量通过指针指向这个内存区域,算是一个优化项,建议打开
默认值8MB, 这里设置为16MB

opcache.max_accelerated_files=10000
控制opcache最多可以在内存中保存多少个 PHP 文件,使用以下命令快速计算代码库中的文件数。

$ find . -type f -print | grep php | wc -l
7183

laravel10的文件7000多个,设置为10000以防万一

opcache.fast_shutdown = 1
如果启用,将使用快速关闭序列,它不会释放每个分配的块,而是依赖 Zend Engine 内存管理器来释放整个请求变量集。
该指令已在 PHP 7.2.0 中删除。快速关闭序列的一个变体已集成到 PHP 中,如果可能,将自动使用。

第二次压测 开启Opcache

# ./go-stress-testing-linux -c 50 -n 6 -u http://192.168.6.32/photos/

 开始启动  并发数:50 请求数:6 请求参数: 
request:
 form:http 
 url:http://192.168.6.32/photos/ 
 method:GET 
 headers:map[Content-Type:application/x-www-form-urlencoded; charset=utf-8] 
 data: 
 verify:statusCode 
 timeout:30s 
 debug:false 
 http2.0:false 
 keepalive:false 
 maxCon:1 


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────
 耗时│ 并发数│ 成功数│ 失败数│   qps  │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 状态码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────
   0s│     50│    300│      0│  849.37│  145.04│    5.32│   58.87│   3,600│   9,228│200:300


*************************  结果 stat  ****************************
处理协程数量: 50
请求总数(并发数*请求数 -c * -n): 300 总请求时间: 0.390 秒 successNum: 300 failureNum: 0
tp90: 87.000
tp95: 98.000
tp99: 138.000
*************************  结果 end   ****************************

结论

没开Opcache之前, 300 总请求时间: 4.946 秒
打开Opcache之后, 300 总请求时间: 0.390 秒
想了下,主要时压测接口只输出了Hello World! 差别才这么夸张
正常的接口IO会花费固定的时间,opcache对IO没有加速作用

推荐生产环境配置

opcache.enable = 1
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.memory_consumption=128 
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.fast_shutdown = 1 //PHP7.2之后无需再配

开发环境不推荐打开,不然可能会被同事追着打!

原理 有空再看

http://blog.jpauli.tech/2015-03-05-opcache-html/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容