Linux 下监控文件自动实现swoole framework热更新
来源:互联网 发布:php安装教程 linux 编辑:程序博客网 时间:2024/06/05 12:46
swoole是以cli运行的,然后长驻内存的。整个生命周期只有在启动的时间可以一次执行RINT过程, 之后所有的请求都在第三步以内完成。(这也是swoole更快的原因之一),这样的话,相关的php脚本如果被执行了一次,就永久性的长驻内存了,更新代码就没有效果了。如果想让代码生效就要重启swoole服务,这种做法是比较粗暴和繁琐。如何才能实现自动检测代码文件?代码自动生效?
在网上查到说使用runkit扩展,经过我测试发现不生效(可能我配置的不对)。
后来找了一个可行的方法,进过整理修改,测试成功。具体步骤如下:
安装inotify扩展
pecl install inotify
在php.ini 最下添加
extension=inotify.so
用于监控文件
创建PHP文件
在 swoole/ToolKit 目录下创建
AutoReload.php
<?phpnamespace Swoole\ToolKit;class NotFound extends \Exception{}class AutoReload{ /** * @var resource */ protected $inotify; protected $pid; protected $reloadFileTypes = array('.php' => true); protected $watchFiles = array(); protected $afterNSeconds = 1; /** * 正在reload */ protected $reloading = false; protected $events; /** * 根目录 * @var array */ protected $rootDirs = array(); public function putLog($log) { $_log = "[" . date('Y-m-d H:i:s') . "]\t" . $log . "\n"; echo $_log; } /** * @param $serverPid * @throws NotFound */ public function __construct($serverPid) { $this->pid = $serverPid; if (posix_kill($serverPid, 0) === false) { throw new NotFound("Process#$serverPid not found."); } $this->inotify = inotify_init(); $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; swoole_event_add($this->inotify, function ($ifd) { $events = inotify_read($this->inotify); if (!$events) { return; } // var_dump($events); foreach ($events as $ev) { if ($ev['mask'] == IN_IGNORED) { continue; } else if ($ev['mask'] == IN_CREATE or $ev['mask'] == IN_DELETE or $ev['mask'] == IN_MODIFY or $ev['mask'] == IN_MOVED_TO or $ev['mask'] == IN_MOVED_FROM) { $fileType = strrchr($ev['name'], '.'); //非重启类型 if (!isset($this->reloadFileTypes[$fileType])) { continue; } } //正在reload,不再接受任何事件,冻结1秒 if (!$this->reloading) { $this->putLog("after 1 seconds reload the server"); //有事件发生了,进行重启 swoole_timer_after($this->afterNSeconds * 1000, array($this, 'reload')); $this->reloading = true; } } }); } public function reload() { $this->putLog("reloading"); //向主进程发送信号 posix_kill($this->pid, SIGUSR1); //清理所有监听 $this->clearWatch(); //重新监听 foreach ($this->rootDirs as $root) { $this->watch($root); } //继续进行reload $this->reloading = false; } /** * 添加文件类型 * @param $type */ public function addFileType($type) { $type = trim($type, '.'); $this->reloadFileTypes['.' . $type] = true; } /** * 添加事件 * @param $inotifyEvent */ public function addEvent($inotifyEvent) { $this->events |= $inotifyEvent; } /** * 清理所有inotify监听 */ public function clearWatch() { foreach ($this->watchFiles as $wd) { inotify_rm_watch($this->inotify, $wd); } $this->watchFiles = array(); } /** * @param $dir * @param bool $root * @return bool * @throws NotFound */ public function watch($dir, $root = true) { //目录不存在 if (!is_dir($dir)) { throw new NotFound("[$dir] is not a directory."); } //避免重复监听 if (isset($this->watchFiles[$dir])) { return false; } //根目录 if ($root) { $this->rootDirs[] = $dir; } $wd = inotify_add_watch($this->inotify, $dir, $this->events); $this->watchFiles[$dir] = $wd; $files = scandir($dir); foreach ($files as $f) { if ($f == '.' or $f == '..') { continue; } $path = $dir . '/' . $f; //递归目录 if (is_dir($path)) { $this->watch($path, false); } //检测文件类型 $fileType = strrchr($f, '.'); if (isset($this->reloadFileTypes[$fileType])) { $wd = inotify_add_watch($this->inotify, $path, $this->events); $this->watchFiles[$path] = $wd; } } return true; } public function run() { swoole_event_wait(); }}
在 swoole 文件夹下创建
daemon.php
<?phprequire __DIR__ . '/ToolKit/AutoReload.php';//存放SWOOLE服务的PID$file = __DIR__ . '/../../examples/app_server.pid';if (file_exists($file)) { $pid = file_get_contents($file); $kit = new Swoole\ToolKit\AutoReload((int)$pid); $kit->watch(__DIR__ . '/../../');//监控的目录 $kit->run();}
创建启动脚本
vim swoole.sh
#!/bin/bashapppidpath="/var/www/examples/app_server.pid"pid="/tmp/swoole.pid" #进程锁定if [ -e $pid ]then exit 0fiecho $$ > ${pid} if [ -f ${apppidpath} ] then nohup php /var/www/libs/Swoole/daemon.php </dev/null &>/dev/null & echo "deamon is ok!" else echo "swoole is stopped!" fi#删除锁定文件rm $pid -rf
chmod +x swoole.sh
启动监控程序
./swoole.sh
至此,Linux监控文件自动实现swoole framework热更新部署完成,大家可以修改代码看看是否生效。
如果在使用过程中出现什么问题,欢迎批评指正。如有好的建议,也希望能给予回复,再次感谢。
阅读全文
0 0
- Linux 下监控文件自动实现swoole framework热更新
- swoole之代码热更新实现
- swoole中的php代码热更新
- swoole中的php代码热更新
- linux下c++实现文件监控
- Linux下使用inotify实现文件监控
- 使用php的swoole扩展实现数据实时更新(下)
- frameWork热更新
- Linux下swoole环境搭建
- Linux下搭建Swoole服务
- Linux下swoole环境搭建
- Linux下使用inotify实现对文件的监控
- linux下vue热更新失败的解决方法
- android实现热更新,打补丁,进行差异文件修复
- Swoole Framework 入门教程(3)-风骚的入口文件
- quick-cocos2d-x的热更新机制实现<五>对 framework 的修改
- 用swoole framework 实现远程接口调用RPC
- 双机热备与监控 (数据库同步,物理文件同步,自动切换服务器)完善中....
- 指定码表读写字符
- Java中的锁
- Android 仿iOS的PickerView控件
- 递归
- 将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
- Linux 下监控文件自动实现swoole framework热更新
- 获取一个文本上每个字符出现的次数,将结果写在times.txt上
- IO流知识,模拟试用版软件
- 信号 核心转储 gdb调试
- 从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名
- 垃圾电话能罚多狠?这个人被罚1.2亿美元
- 闲话架构师的职责
- gerrit的第一次提交记录
- CRC校验