easyswoole - 基于swoole扩展实现的一款高性能php框架

雙機熱備

1. 介紹

文章主要介紹,EasySwoole 使用雙機熱備思路實現代碼不中斷部署。

2. 學習案例

    1. 先部署 9501 服務
    1. 單起一個進程,定時輪詢 Git 分支是否有新版本發布
    1. 如有新版本發布,clone 一份
    1. composer update 更新庫
    1. 啟動 9502 服務
    1. 更改 nginx 配置為 9502 并重啟

只要有新版本發布,就輪詢上面那幾個步驟

整個過程的簡單架構圖

image.png

3. 需要提前了解的知識點

  1. Nginx 負載均衡和反向代理
  2. EasySwoole 自定義進程
  3. Nginx reload 和 restart 的區別
  4. 雙機熱備

4. Nginx 配置

nginx.conf 配置文件示例

當有新版本發布的時候 EasySwoole 自定義進程會將 nginx.conf 的端口改為最新服務的端口

worker_processes  1;

events {
    worker_connections  1024;
}

http {

    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    sendfile        on;

    keepalive_timeout  65;

    ### 輪詢配置(這里是重點)
    upstream  easyswoole_release_upstream {
        server 127.0.0.1:9501;
        server 127.0.0.1:9502;
    }

    include servers/*;
}

es-release.conf 站點配置文件

該配置文件在 servers 目錄下。(此示例是以 Mac 本地環境作為運行環境)

server {
    listen 80;
    server_name easyswoole.release.com;

    location / {
        root html;
        index index.html index.htm;
        proxy_pass http://easyswoole_release_upstream; ### 這里是重點
    }
    access_log /usr/local/etc/nginx/logs/es.access.log main;
    error_log /usr/local/etc/nginx/logs/es.error.log error;
}

5. EasySwoole 代碼實現

代碼只提供實現思路,并且這種腳本,最好單獨去做,比如用 shell 腳本,防止服務宕機導致無法正常部署代碼

創建自定義進程類文件

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://www.zbjtqy.com
 * @document http://www.zbjtqy.com
 * @contact http://www.zbjtqy.com/Preface/contact.html
 * @license https://github.com/easy-swoole/easyswoole/blob/3.x/LICENSE
 */

namespace App\Release;

use EasySwoole\Component\Process\AbstractProcess;
use Swoole\Coroutine;

class Release extends AbstractProcess
{
    public function dolog($msg, $filename = '/Users/xxx/sites/release_log.log')
    {
        if ($msg) {
            error_log($msg . PHP_EOL, 3, $filename);
        }
    }

    protected function run($arg)
    {
        go(function () {
            while (true) {
                $shellLog = ' 2>> /Users/xxx/sites/release_log.log';
                $this->dolog(date('Y-m-d H:i:s') . '開始檢測代碼是否更新 ===> START <=== ');
                // 檢查 Git 是否有新代碼發布
                $diffExec = 'cd ' . EASYSWOOLE_ROOT . '; git fetch; git diff --stat master origin/master;';
                $this->dolog($diffExec);
                $pullResult = exec($diffExec);

                $this->dolog('git fetch res: => ' . json_encode($pullResult));

                if ($pullResult !== '') {
                    $this->dolog('有新版本發布' . json_encode($pullResult));
                    // 新版本項目的目錄
                    $newVersionPath = '/Users/xxx/sites/release-' . time();

                    // 開始 clone, 初始化代碼
                    ### 這里需要換成自己的 EasySwoole 項目的 github 地址
                    $cloneExec = "git clone https://github.com/huizhang-Easyswoole/release.git {$newVersionPath} {$shellLog};cd {$newVersionPath} {$shellLog};composer update {$shellLog}; {$shellLog}";
                    $this->dolog($cloneExec);

                    $res = exec($cloneExec, $output, $returnVar);
                    $this->dolog('git clone res: => ' . json_encode($res, JSON_UNESCAPED_UNICODE));
                    $this->dolog('新版本代碼 clone end');

                    // 判斷當前是哪個端口正在服務
                    $lsofExec = "lsof -i:9501 {$shellLog}";
                    $this->dolog($lsofExec);
                    $lsofResult = exec($lsofExec);
                    $newPort = 9501;
                    $oldPort = 9502;
                    if ($lsofResult !== '') {
                        $newPort = 9502;
                        $oldPort = 9501;
                    }

                    // 將另一個閑置的端口,替換到新版本中
                    $this->dolog('開始替換端口' . $newPort);
                    $devConfig = file_get_contents($newVersionPath . '/dev.php');
                    $devConfig = str_replace($oldPort, $newPort, $devConfig);
                    file_put_contents($newVersionPath . '/dev.php', $devConfig);

                    // 啟動新服務(這一刻新舊服務是同時存在的)
                    $this->dolog('新服務啟動');
                    $startExec = "cd {$newVersionPath}; php easyswoole.php server start -d {$shellLog}";
                    $this->dolog($startExec);
                    exec($startExec);

                    // 替換 Nginx 配置
                    $this->dolog('開始替換 nginx 端口');
                    ### 這里需要換成自己服務器環境 nginx 配置文件所在的目錄
                    $ngConfigPath = '/usr/local/etc/nginx/nginx.conf';
                    $ngConfig = file_get_contents($ngConfigPath);
                    $ngConfig = str_replace($oldPort, $newPort, $ngConfig);
                    file_put_contents($ngConfigPath, $ngConfig);

                    // 重啟 Nginx 服務
                    $this->dolog('重啟 nginx ');
                    $reloadNgExec = "nginx -s reload {$shellLog}";
                    $this->dolog($reloadNgExec);
                    exec($reloadNgExec);

                    // 停掉舊服務
                    $this->dolog('舊服務停掉');
                    $stopExec = "cd " . EASYSWOOLE_ROOT . "; php easyswoole.php server stop {$shellLog}";
                    $this->dolog($stopExec);
                    exec($stopExec);

                    // 每 30 秒同步一次代碼
                    Coroutine::sleep(30);
                } else {
                    Coroutine::sleep(10);
                    $this->dolog('無新版本更新');
                }
            }
        });
    }
}

注冊自定義進程

在框架的 EasySwooleEvent 事件(即項目根目錄的 EasySwoolEvent.php)中注冊自定義進程,示例代碼如下:

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://www.zbjtqy.com
 * @document http://www.zbjtqy.com
 * @contact http://www.zbjtqy.com/Preface/contact.html
 * @license https://github.com/easy-swoole/easyswoole/blob/3.x/LICENSE
 */

namespace EasySwoole\EasySwoole;

use App\Release\Release;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        ###### 注冊 雙機熱備服務 自定義進程 ######
        $processConfig = new \EasySwoole\Component\Process\Config([
            'processName' => 'Es-release', // 設置 自定義進程名稱
            'processGroup' => 'Es-release', // 設置 自定義進程組名稱
        ]);
        \EasySwoole\Component\Process\Manager::getInstance()->addProcess(new Release($processConfig));
    }
}

6. 測試

綁定 host

127.0.0.1 easyswoole.release.com

訪問 easyswoole.release.com

image.png

查看 Nginx 配置的端口

?  nginx cat nginx.conf | grep 950
           server    127.0.0.1:9501;

發布新版本

重新 clone 一份代碼,更改內容提交。

查看Nginx配置的端口

?  nginx cat nginx.conf | grep 950
           server    127.0.0.1:9502;
主站蜘蛛池模板: 生物可降解膜_全降解薄膜_可降解包装膜材料厂家-凯峰降解膜 | 轻质隔墙板厂家-加气隔墙板_grc轻质隔墙板_空心实心复合隔墙板_水泥混凝土轻质隔墙板批发价格 | 智汇工业-智慧工业、智能制造及工业智能、工业互联门户网站,专业的工业“互联网+”传媒 | 英格索兰隔膜泵_ARO气动隔膜泵_英格索兰隔膜泵配件【原厂正品】连续五年无投诉_英格索兰隔膜泵代理-苏州瑞晟茂环保设备有限公司 印刷公司,北京印刷厂,宣传画册手册印刷厂-和智印彩页设计 | 液压尾管悬挂器,机械式尾管悬挂器价格,石油套管扶正器厂家,连续油管悬挂器,高压双塞水泥头,免钻塞注水泥分级箍,单塞套管水泥头价格,弹性套管扶正器,铸铝钢性扶正器,钢性套管扶正器厂家 | 山东货架厂家,重型货架,阁楼货架,钢平台,板材货架-山东智造仓储设备有限公司 | 热水工程|空气能热水工程|超低温采暖工程|太阳能热水工程|空气源热泵厂家|炬邦热能设备有限公司 热熔钻孔机【优质厂家】_多年热熔钻设备研发制造经验 | 武汉凯美隆窗帘厂家_定做商用窗帘_家用遮阳帘_涵盖电动窗帘_天棚帘_遮阳棚_凯美隆-专注遮阳产品 武汉净化机-武汉全热新风换气机-武汉静音送风机-武汉东信新风节能设备有限公司 | 生物除臭剂-养殖场垃圾除臭剂-垃圾填埋场除臭剂-成都微菌环境 | 悬挂式小鼠笼架,植物标本采集箱,昆虫标本盒厂家-北京合力科创科技发展有限公司 | 上海浩斌信息科技有限公司RFID读写器,IC卡读卡器,手持机,数据采集终端,电力仓库管理软件开发,固定资产软件,纱管标签,试剂管理,RFID试剂柜,档案管理,档案柜,智能货架 | 衡水物流网,衡水物流信息网,衡水物流公司,衡水货运专线,衡水专线运输车辆 | 纸箱抗压测定仪|电脑测控耐破度仪|电脑抗张试验仪|杭州华翰仪器百科 | 数据交易导航,数据资产入表,数据交易平台,数据要素市场 | 压力蒸汽灭菌器_脉动真空灭菌器_环氧乙烷灭菌器_等离子灭菌器_广州市科洋 | 随车吊,洒水车,吸污车-程力专用汽车股份有限公司 | 聚焦吉林-城市晚报官方网站| 阻抗分析仪 阻抗测试仪 介电常数测试仪 充电枪测试仪-苏州腾斯凯电子科技有限公司 | 智能访客系统 - 来访登记系统_微信预约系统_人员出入管理系统_访客机_人脸识别系统门禁闸机 | 曙海培训-仿真培训Linux培训html5培单片机培训PCB培训python培训PLC培训C语言培训android培训物联网培训无线电培训欧姆龙培训工业机器人培训5G培训Hadoop培训CFD培训项目外包开发咨询 | 上海办公家具_高端实木办公家具_现代智能办公家具定制厂-上海迈亚家具有限公司 | 泰安铭德机械有限公司,有机肥设备,山东有机肥设备厂家,铭德机械 泰安华特玻璃钢有限公司|泰安玻璃钢|泰安华特玻璃钢 | 友联智能|RFID应用服务供应商|专注RFID行业解决方案|RFID数据采集-助力行业数字化转型 | 文学素材,好词好句,正能量句子,百科知识-素文网 | 苏州温测仪器有限公司-苏州炉温跟踪仪|苏州隔热箱|苏州炉温测试仪|苏州恒温恒湿箱 | 环保白电油_甲醇_二价酸酯DBE_防白水-【名亿新材料】 | 十堰急开锁0719-8888139|十堰开锁公司|十堰开锁电话|十堰换锁价格-同福锁城-十堰同福锁城 | 潍坊网络推广,临沂360推广,东营360推广,枣庄360推广,潍坊网站建设,潍坊网络公司,潍坊360搜索,潍坊APP开发,潍坊360推广,潍坊360代理,潍坊点睛网络科技有限公司 | 上海消防器材|水雾喷头|水幕喷头|螺旋喷头|雾化喷头|泡沫喷头 - 上海舜丹消防设备有限公司 | 联塑管代理,联塑管厂家批发,中财管总代理,康泰管代理,康泰管厂家批发-邯郸市中枢贸易有限公司 | 西安泰富西玛电机有限公司总部-电机-高压电机-西玛电机-西安西玛电机-泰富西玛电机-西安电机厂-西玛电机销售 | 四川蜀易控科技有限公司-酒店客房控制系统-智慧酒店智能化客房控制系统生产厂家 | 喵走共享单车网 - 共享电动车_共享电单车骑行门户网站 倡导绿色出行 | 售后服务认证-五星级物业售后服务体系认证证书-ISO27001信息安全管理体系认证证书查询认E云-湖北省贯标企业管理咨询有限公司 | 铝合金热处理设备_天然气铝棒加热炉_QPQ热处理设备-浙江长兴天源炉业科技有限公司 | 鲜淘网 - 精选全球水果蔬菜肉食海产生鲜,酒水食品零食加盟供求信息 | 螺带混合机|卧式螺带混合机|双动力混合机-无锡鑫海干燥粉体设备有限公司 | 陕西筱润智能科技有限公司 干部人事智能档案柜 智能密集架 智能档案柜 部队选层文件智能柜 智能枪弹柜 财务智能档案柜 边防武警智能密集架 医院智能档案柜 部队选层文件智能柜智能枪弹柜 学校医院文件柜 企事业单位公检法智能文件柜 生产厂家-筱润智能科技有限公司 RFID射频智能密集架 全自动智能选层档案柜 智能密保柜 枪柜部队营房营具床桌椅办公家具 办公用品档案盒设备货架 全自动智能选层柜生产厂家-筱润智能科技有限公司 | 耐磨钢板_复合耐磨板_KN60耐磨钢板-北京耐默公司 | 厦门,泉州自助餐上门|生日自助餐|婚礼自助餐|公司聚会自助餐|户外烧烤|冷餐|茶歇外卖配送-福建非选餐饮公司 | 水处理设备_纯净水设备_软化水设备_反渗透水处理设备「陕西甘肃青海宁夏新疆」认准海川环保 |