談談 opcache 的一些碎雜事(一不當心服務器內存就撐爆了)php
在PHP的應用中,說到優化,不得不提到opcache,在PHP5.6+,咱們能夠開啓opcache來,提高咱們網站的訪問速度,因此用好opcache能幫咱們提高效率。git
在opcache生效中,有兩個主要配置github
opcache.validate_timestamps=1;web
opcache.revalidate_freq=10;api
1.當validate_timestamps設置0時, opcache.revalidate_freq的值將失效,validate_timestamps做用主要驗證是否要從新生成緩存腳本,PHP將不會檢測代碼是否改變,這樣會致使部署更新的代碼後,不會自動生成新的緩存,就致使仍是顯示原來的舊代碼; 固然,能夠設置爲 0(這樣性能最佳的),可是這個通常適合於不頻繁更新的PHP 代碼,每次更改後須要手動清除 opcache,即須要平滑加載php-fpm。緩存
2.當validate_timestamps設置1時,opcache.revalidate_freq的值將生效,在opcache.revalidate_freq設置的時間值,PHP將會從新生成代碼緩存。bash
接下來看開啓opcache 會致使什麼問題服務器
首先,我在給兩個在運行的PHP項目添加opcachecurl
配置ide
[opcache] zend_extension=opcache.so opcache.enable=1 opcache.memory_consumption=384 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=100000 opcache.max_wasted_percentage=5 opcache.use_cwd=1 opcache.validate_timestamps=1 opcache.revalidate_freq=60 opcache.save_comments=0 opcache.fast_shutdown=1 opcache.consistency_checks=0
項目一:是一個不多的代碼更新的PHP項目(主機一)
項目二:是一個頻繁更新的PHP項目,cli與php-fpm(主機二)
未開啓前,查看兩個主機的內存使用狀況
主機一:
# free -m total used free shared buff/cache available Mem: 7774 1636 636 35 5500 5804 Swap: 0 0 0
主機二:
# free -m total used free shared buff/cache available Mem: 15830 6228 2765 1318 6836 7073 Swap: 5887 0 5887
兩臺配置opcache ,主機二頻繁的跟新PHP代碼 ,等了一段時間後再查看一下,
主機一:
# free -m total used free shared buff/cache available Mem: 7774 1641 630 37 5502 5797 Swap: 0 0 0
主機二:
# free -m total used free shared buff/cache available Mem: 15830 14202 339 11208 1288 298 Swap: 5887 0 5887
好傢伙,主機二所在的內存使用,差點就滿了,主機二所在的地方有比較多的PHP項目,看到這種狀況,立馬中止了opcache。
問題分析:爲何會出現這種問題呢?
分析一:
可能因爲個人PHP項目跟新代碼的方式是經過軟連所生成的web目錄,opcache 是經過文件的真實路徑進行緩存的,這就致使了每次部署都會生成緩存字節碼,那麼就致使了舊的緩存沒有被清理,也致使咱們的內存沒法釋放,從而致使內存給撐滿了。
分析二:
多是在 執行cli 命令行下執行此函數並不能清理 php-fpm 下生成的緩存字節碼,也會大量產生緩存,會嚴重消耗內存、cpu。
問題處理:
按照分析是什麼緣由引發,那就好處理了。
方法一:
平滑重啓PHP,可是對於那些頻繁跟新的PHP項目並非很實用,這裏略過
方法二:
經過第三方庫 cachetool工具,實現對緩存的刷新控制。
Cachetool工具使用
安裝cachetool-4.1.1.phar ,版本 PHP >=7.1
下載安裝:
curl -sO https://gordalina.github.io/cachetool/downloads/cachetool-4.1.1.phar chmod +x cachetool-4.1.1.phar mv cachetool-4.1.1.phar cachetool.phar
最新的能夠下載:
curl -sO https://github.com/gordalina/cachetool/releases/latest/download/cachetool.phar chmod +x cachetool.phar
查看用法:
php /usr/local/cachetool/cachetool.phar --fcgi=/dev/shm/php-cgi.sock
注意:--fcgi參數配置主要爲sock和127.0.0.1:9000兩種
查看PHP的opcache的緩存狀態:
php /usr/local/cachetool/cachetool.phar opcache:status --fcgi=/dev/shm/php-cgi.sock
清除PHP緩存:
php /usr/local/cachetool/cachetool.phar opcache:reset --fcgi=/dev/shm/php-cgi.sock
查看緩存是否已經被清理
之後用法,能夠經過更新代碼後更新緩存
問題再次出現
原本,覺得經過以上的方法,清理每一次上線的代碼緩存,就不會致使內存擠滿的,但是現實很打臉,內存大概10來分鐘,又被擠滿了,內存,cpu 直達100%,任何操做都作不了,被迫強制關機。
好了。咱們經常使用的php通常有兩種運行方式,一種是php-fpm ,另外一種是cli,而我,偏偏忽略cli的運行方式。而Cli運行方式,也會加載讀取php.ini配置文件,也會消耗內存。
處理辦法:
找了不少的opcache配置解析,發現忽略一個很重要的一個參數opcache.enable_cli,好像發現了,就是這個致使的,這個就是致使cli,佔用大量的內存,並且沒法清理,而引發系統內存崩潰。
添加配置
opcache.enable_cli=0
使用命令獲取內存使用狀況
一直監控了好久,使用很正常,調試方向,沒錯了,
而最後接口返回時間對比一下
優化前
優化後
而經過curl獲取點時間
curl -o /dev/null -s -w '%{time_connect}:%{time_starttransfer}:%{time_total}\n' 'http://api.test.com' 0.067740:0.097896:0.098095
總結:
在應用opccache中 。必定要把握opcache.enable_cli 配置參數的應用;而最後的實踐對比驗證也很重要了。