Opcache實(shí)戰(zhàn)

簡述

字節(jié)碼緩存不是PHP的新特性,有很多獨(dú)立的第三方擴(kuò)展實(shí)現(xiàn)了字節(jié)碼緩存,例如APC,eAccelerator等,從PHP5.5開始內(nèi)置了字節(jié)碼緩存功能,名為Zend Opcache
開啟字節(jié)碼緩存之后,PHP解釋器不用每次都讀取,解析,編譯PHP代碼,直接從共享內(nèi)存中讀取opcode(字節(jié)碼),極大地提升應(yīng)用性能

環(huán)境

  • 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()
    {
            // 引入的文件總數(shù) 469個(gè)
            `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/

 開始啟動  并發(fā)數(shù):50 請求數(shù):6 請求參數(shù): 
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 


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────
 耗時(shí)│ 并發(fā)數(shù)│ 成功數(shù)│ 失敗數(shù)│   qps  │最長耗時(shí)│最短耗時(shí)│平均耗時(shí)│下載字節(jié)│字節(jié)每秒│ 狀態(tài)碼
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────
   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


*************************  結(jié)果 stat  ****************************
處理協(xié)程數(shù)量: 50
請求總數(shù)(并發(fā)數(shù)*請求數(shù) -c * -n): 300 總請求時(shí)間: 4.946 秒 successNum: 300 failureNum: 0
tp90: 963.000
tp95: 1020.000
tp99: 1134.000
*************************  結(jié)果 end   ****************************

推薦配置

opcache.enable = 1
設(shè)置為 1,開啟 Opcache 功能。

opcache.validate_timestamps=0
設(shè)置為1表示將根據(jù)您的 opcache.revalidate_freq 值檢查文件時(shí)間戳判斷文件有沒有更改
生產(chǎn)環(huán)境中配置為0,生產(chǎn)環(huán)境不需要驗(yàn)證文件變動,每次更新部署代碼的時(shí)候,重啟fpm即可,systemctl restart php8.2-fpm.service或者kill -SIGUSR2 pid
順便解決了上代碼的時(shí)候文件新舊混合的問題,就是說你要上100個(gè)文件,上傳完之前,總會出現(xiàn)50個(gè)新文件,50個(gè)舊文件的時(shí)刻,可能會發(fā)生一些不愉快的結(jié)果
其實(shí)開發(fā)環(huán)境也不太需要用到opcache,所以這個(gè)值無腦設(shè)置為0

opcache.revalidate_freq=0
當(dāng)validate_timestamps=1時(shí)這個(gè)設(shè)置才有用
opcache緩存時(shí)間,設(shè)置為0表示每次都要檢查校驗(yàn)文件時(shí)間戳判斷文件有沒有改變,這里會用到系統(tǒng)調(diào)用stat
當(dāng)validate_timestamps=0時(shí),這個(gè)值不需要設(shè)置

opcache.memory_consumption=128
可以使用函數(shù) opcache_get_status() 來了解 opcache 消耗了多少內(nèi)存以及是否需要增加數(shù)量
也可以在phpinfo()查看緩存詳情

image.png

默認(rèn)值64MB,這里設(shè)置為128MB

opcache.interned_strings_buffer=16
在php-fpm進(jìn)程組之間使用16MB共享內(nèi)存來存儲公共字符串,比如很幾百個(gè)類都有個(gè)字符串變量值為hello world,啟用這個(gè)選項(xiàng)后,只需要在共享內(nèi)存里面存一次hello world,變量通過指針指向這個(gè)內(nèi)存區(qū)域,算是一個(gè)優(yōu)化項(xiàng),建議打開
默認(rèn)值8MB, 這里設(shè)置為16MB

opcache.max_accelerated_files=10000
控制opcache最多可以在內(nèi)存中保存多少個(gè) PHP 文件,使用以下命令快速計(jì)算代碼庫中的文件數(shù)赖草。

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

laravel10的文件7000多個(gè),設(shè)置為10000以防萬一

opcache.fast_shutdown = 1
如果啟用学少,將使用快速關(guān)閉序列,它不會釋放每個(gè)分配的塊秧骑,而是依賴 Zend Engine 內(nèi)存管理器來釋放整個(gè)請求變量集版确。
該指令已在 PHP 7.2.0 中刪除『跽郏快速關(guān)閉序列的一個(gè)變體已集成到 PHP 中绒疗,如果可能,將自動使用骂澄。

第二次壓測 開啟Opcache

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

 開始啟動  并發(fā)數(shù):50 請求數(shù):6 請求參數(shù): 
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 


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────
 耗時(shí)│ 并發(fā)數(shù)│ 成功數(shù)│ 失敗數(shù)│   qps  │最長耗時(shí)│最短耗時(shí)│平均耗時(shí)│下載字節(jié)│字節(jié)每秒│ 狀態(tài)碼
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────
   0s│     50│    300│      0│  849.37│  145.04│    5.32│   58.87│   3,600│   9,228│200:300


*************************  結(jié)果 stat  ****************************
處理協(xié)程數(shù)量: 50
請求總數(shù)(并發(fā)數(shù)*請求數(shù) -c * -n): 300 總請求時(shí)間: 0.390 秒 successNum: 300 failureNum: 0
tp90: 87.000
tp95: 98.000
tp99: 138.000
*************************  結(jié)果 end   ****************************

結(jié)論

沒開Opcache之前, 300 總請求時(shí)間: 4.946 秒
打開Opcache之后, 300 總請求時(shí)間: 0.390 秒
想了下,主要時(shí)壓測接口只輸出了Hello World! 差別才這么夸張
正常的接口IO會花費(fèi)固定的時(shí)間,opcache對IO沒有加速作用

推薦生產(chǎn)環(huán)境配置

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之后無需再配

開發(fā)環(huán)境不推薦打開,不然可能會被同事追著打!

原理 有空再看

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吓蘑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坟冲,更是在濱河造成了極大的恐慌磨镶,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件健提,死亡現(xiàn)場離奇詭異琳猫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)私痹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門沸移,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痪伦,“玉大人,你說我怎么就攤上這事雹锣⊥矗” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵蕊爵,是天一觀的道長辉哥。 經(jīng)常有香客問我,道長攒射,這世上最難降的妖魔是什么醋旦? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮会放,結(jié)果婚禮上饲齐,老公的妹妹穿的比我還像新娘。我一直安慰自己咧最,他們只是感情好捂人,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矢沿,像睡著了一般滥搭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捣鲸,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天瑟匆,我揣著相機(jī)與錄音,去河邊找鬼栽惶。 笑死愁溜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的外厂。 我是一名探鬼主播祝谚,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酣衷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起次泽,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤穿仪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后意荤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啊片,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年玖像,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紫谷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笤昨,靈堂內(nèi)的尸體忽然破棺而出祖驱,到底是詐尸還是另有隱情,我是刑警寧澤瞒窒,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布捺僻,位于F島的核電站,受9級特大地震影響崇裁,放射性物質(zhì)發(fā)生泄漏匕坯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一拔稳、第九天 我趴在偏房一處隱蔽的房頂上張望葛峻。 院中可真熱鬧,春花似錦巴比、人聲如沸术奖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腰耙。三九已至,卻和暖如春铲球,著一層夾襖步出監(jiān)牢的瞬間挺庞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工稼病, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留选侨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓然走,卻偏偏與公主長得像援制,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子芍瑞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容