關於使用supervisor
守護的php腳本任務,如何檢測自己的代碼有變更,然後自動重新啓動的問題
這裏不討論由 cron 執行 php 腳本的方式, 因爲它每個循環都會重新加載代碼
思路
常駐進程的代碼, 內部肯定有個循環讀取數據並處理數據的邏輯, 我們只要在這裏加上判斷,然後終止當前程序,再由supervisor
重新啓動即可.
-
在腳本啓動時, 用
filemtime()
獲取當前腳本文件的修改時間, 記錄到變量 -
在內部循環中, 檢查當前腳本文件的最後修改時間. 如果記錄比當前值小, 則退出當前程序
如果這個腳本文件引用的其他文件有變更, 但是它自己沒有變更怎麼辦呢? 難道要判斷所有加載的文件是否變更嗎? 那樣成本有點大了, 當然你也可以這麼做.
建議在這個腳本文件中, 定義一個版本號, 每次修改或關聯文件修改後都去更新一下版本號, 以確保文件更新被識別到.
代碼示例
示例代碼:
//當前文件路徑
$file_path = __DIR__ . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_NAME'];
//文件修改時間
$file_update_time = filemtime($file_path);
//版本號
$version = 123;
//是否是第一次循環. 第一次不判斷文件是否變更
$first_loop = true;
while (true) {
if (!$first_loop) {
//這裏必須先清除PHP函數結果的緩存
clearstatcache(true, $file_path);
if (filemtime($file_path) > $file_update_time) {
//文件改變, 退出當前程序
echo 'Changed' . PHP_EOL;
break;
}else{
echo 'not changed...' . PHP_EOL;
}
}
$first_loop = false;
sleep(1);
}
在workerman中監控文件更新並自動reload, 也是類似的操作. 只是我們這裏只有一個進程, 不能用另外的worker來執行檢測任務.
注意
1、 clearstatcache()
的使用
爲了提高性能,PHP對部分函數的結果進行了緩存。 受影響的函數包括 stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype() 和 fileperms()。
2、在PHPStorm中編碼時
在PHPStorm的terminal中執行腳本, 在代碼編輯區修改並查看循環狀態時,務必修改後讓鼠標離開編輯區(或者手動保存), 否則ps不會保存文件, 也就看不到結果