一次快取事故排查
周天安排做支付,使用支付寶介面對接,閱讀了pdf和demo,自我感覺可以了,在本地上寫好相關程式碼,傳到伺服器上,整備除錯,問題就接著出來了。
一般除錯,我喜歡列印語句看看,邏輯是否照著我的思路走,以便知道錯誤程式碼在哪。可在伺服器列印時,卻一直顯示上一次的除錯結果。如,一開始我輸出111,接著,我改為輸出222,重新整理網頁,尼瑪,還是111,過了將近1分多鐘,才變為222。習慣的,我認為應該是使用的框架開啟了快取,於是我開始看伺服器上的快取配置檔案,shit,相應的狀態都是關著的,我又去了快取目錄看了下,沒發現有檔案生成,這見了鬼呢。於是我把斷掉除錯的範圍提升了,直接放在框架入口處,還是一樣的,那麼說明,壓根就沒有進入到框架中去,也就不是框架快取配置的問題,於是我懷疑是web伺服器快取的緣故,過去開啟看,我勒個去,還是沒有發現相關的配置。
到了山窮水盡的地步了,等等,既然沒有發現快取檔案,那麼肯定是快取在記憶體裡了。為了驗證這個想法,我做了個測試。在根目錄我新建了兩個檔案,一個靜態檔案,一個動態php檔案。首先在靜態檔案輸出,開啟頁面,接著改資訊,重新整理,立馬有變化,接著以同樣的方法測試動態php檔案,又出現了一開始的問題,有快取。恩,應該是快取在記憶體裡了,為了驗證我的想法,我在php檔案裡輸出phpinfo語句,看了看配置資訊,我發現了什麼,Zend OPcache,好傢伙,原來伺服器上了配置了這個。
大夥應該都知道,php是動態語言,每次執行時,都會重新編譯,這會很耗效能的。而Zend OPcache 則是通過 opcode 快取和優化提供更快的 PHP 執行過程。它將預編譯的指令碼檔案儲存在共享記憶體中供以後使用,從而避免了從磁碟讀取程式碼並進行編譯的時間消耗。同時,它還應用了一些程式碼優化模式,使得程式碼執行更快。簡單的瞭解了Zend OPcache作用後,那麼就去php配置檔案看看了,果真,在配置檔案的最下方返現這麼寫配置資訊
[opcache]zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20121212/opcache.so ;OPcache 的共享記憶體大小,以兆位元組為單位。 opcache.memory_consumption=64 ;用來儲存臨時字串的記憶體大小,以兆位元組為單位。 ;PHP 5.3.0 之前的版本會忽略此配置指令。 opcache.interned_strings_buffer=8 ;OPcache 雜湊表中可儲存的指令碼檔案數量上限。 ;真實的取值是在質數集合 ;{ 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987 } ;中找到的第一個比設定值大的質數。 設定值的取值範圍是 200 到 100000 之間。 opcache.max_accelerated_files=4000 ;如果快取處於非啟用狀態,等待多少秒之後計劃重啟。 ;如果超出了設定時間,則 OPcache 模組將殺除持有快取鎖的程序, 並進行重啟。 ;如果選項 opcache.log_verbosity_level 設定為 3 或者 3 以上的數值, ;當發生重啟時將在日誌中記錄一條錯誤資訊。 opcache.force_restart_timeout=180 ;檢查指令碼時間戳是否有更新的週期,以秒為單位。 ;設定為 0 會導致針對每個請求, OPcache 都會檢查指令碼更新。 ;如果 opcache.validate_timestamps 配置指令設定為禁用,那麼此設定項將會被忽略。 opcache.revalidate_freq=60 ;如果啟用,則會使用快速停止續發事件。 ;所謂快速停止續發事件是指依賴 Zend 引擎的記憶體管理模組 ;一次釋放全部請求變數的記憶體,而不是依次釋放每一個已分配的記憶體塊。 opcache.fast_shutdown=1 ;僅針對 CLI 版本的 PHP 啟用操作碼快取。 通常被用來測試和除錯。 opcache.enable_cli=1
配置檔案裡的“opcache.revalidate_freq=60”是說明,會每隔一分鐘檢測一次指令碼檔案是否更新,那麼就找到問題的根本了,改為0,也就是每次執行時都去檢測一下,重新啟動php,搞定。