关于使用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不会保存文件, 也就看不到结果