Hyperf 生产环境, 不上Swarm, 不上 k8s, 如何更新?
<?php /** * 双机热备更新: * 1、检查当前项目运行端口 9501 * 2、更改项目运行端口为 9502,启动项目(此时运行的是两个服务9501+9502) * 3、更改nginx配置为 9502,并重新 reload * 4、停止9501端口服务 */ #--------------------- 主要修改内容 start ------------------ // 目录 define("WEB_PATH", "/data/web"); // Todo 项目 define("PROJECT_NAME", "cp-game-api"); // Todo nginx配置文件 define("NGINX_CONF", "/usr/local/nginx/conf/vhost/cp-game-api.conf"); // TODO 原先端口 define("PORT", 9501); // Todo 交换端口 define("NEW_PORT", 9502); #--------------------- 主要修改内容 end ------------------ // 完整项目地址 define("PROJECT_PATH", WEB_PATH . "/" . PROJECT_NAME); // RUNTIME define("RUNTIME_PATH", PROJECT_PATH . "/runtime"); // 项目构建日志 define("LOG_FILE", RUNTIME_PATH . "/release.log"); // PID define("PID_FILE", RUNTIME_PATH . "/hyperf.pid"); class Release { public $pid = 0; public function __construct() { // 旧服务pid if (file_exists(PID_FILE)) { $this->pid = file_get_contents(PID_FILE); } } // 判断端口 public function getPort() { $lsofExec = "lsof -i:" . PORT; $lsofResult = exec($lsofExec); $newPort = PORT; $oldPort = NEW_PORT; if ($lsofResult !== '') { $newPort = NEW_PORT; $oldPort = PORT; } return [$oldPort, $newPort]; } // 读取nginx配置,判断当前正在使用的是哪个端口 public function getNginxServerPort() { $fileContent = file_get_contents(NGINX_CONF); $pattern = '/127\.0\.0\.1:(\d+)/'; preg_match($pattern, $fileContent, $matches); return $matches[1] ?? 0; } // 执行正文 public function run() { $this->log(PHP_EOL . date("Y-m-d H:i :s') . ' 版本发布 ===> START <=== '); // 判断当前是哪个端口正在服务 [$oldPort, $newPort] = $this->getPort(); // 将另一个闲置的端口,替换到新版本中 $projectPath = WEB_PATH . "/" . PROJECT_NAME; $this->log(' 新服务端口为:' . $newPort); $devConfig = file_get_contents($projectPath . '/.env'); $devConfig = str_replace($oldPort, $newPort, $devConfig); file_put_contents($projectPath . '/.env', $devConfig); // 启动新服务(这一刻新旧服务是同时存在的) $startExec = "cd {$projectPath}; php bin/hyperf.php start"; $this->log(" 新服务启动:" . $startExec); exec($startExec); // 替换 Nginx 配置 $oldNginxPort = $this->getNginxServerPort(); if ($oldNginxPort && $oldNginxPort != $newPort) { $this->log(' 替换nginx配置端口为:' . NGINX_CONF . ' ==> ' . $newPort); ### 这里需要换成自己服务器环境 nginx 配置文件所在的目录 $ngConfig = file_get_contents(NGINX_CONF); $ngConfig = str_replace($oldNginxPort, $newPort, $ngConfig); file_put_contents(NGINX_CONF, $ngConfig); // 重启 Nginx 服务 $reloadNgExec = "nginx -s reload"; $this->log(" 重载nginx: " . $reloadNgExec); exec($reloadNgExec); } if ($this->pid) { $stopExec = "kill {$this->pid}"; } else { $stopExec = "netstat -tunlp | awk '{if ($4 == " . '"0.0.0.0:' . $oldPort . '"' . ') print $7}\' | awk -F"/" \'{ print $1 }\' | xargs kill -15'; } $this->log(" 停掉旧服务: " . $stopExec); exec($stopExec); $this->log(date("Y-m-d H:i:s") . ' 版本发布 ===> END <=== ' . PHP_EOL); } // 日志记录 public function log($msg, $filename = '') { $filename = $filename ?: LOG_FILE; echo $msg . PHP_EOL; return file_put_contents($filename, $msg . PHP_EOL, FILE_APPEND); } } (new Release())->run(); 本文转自:www.range8.cn/index.php/archives/2...
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
exec这些函数都没有禁用么