五月天激情丁香,国产精品2019,国产成人精品亚洲2020,国产精品免费视频一区二区三区,开心久久婷婷综合中文字幕,天堂视频在线观看免费完整版

雙機熱備

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.fe88.cn
 * @document http://www.fe88.cn
 * @contact http://www.fe88.cn/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.fe88.cn
 * @document http://www.fe88.cn
 * @contact http://www.fe88.cn/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;
主站蜘蛛池模板: 日韩欧美中字 | 精品一区二区三 | 国产不卡的一区二区三区四区 | 精品无人乱码一区二区三区 | 国产视频久久久久 | 欧美大片日韩精品四虎影视 | 婷婷丁香在线观看 | 国产精品视频久久久久久 | 97热在线 | 日本无卡码免费一区二区三区 | 激情五月婷婷小说 | 欧美a在线视频 | 国产精品成人第一区 | 精品视频一区二区三区四区 | 国产成人综合亚洲一区 | 3d动漫精品啪啪一区二区中 | 久久小视频 | 九七电影网97理论片 | 丁香六月网 | 免费的黄网站男人的天堂 | 久久99九九99九九99精品 | 国产精品1区2区3区在线播放 | 97精品在线观看 | 亚洲青草| 国产视频每日更新 | 经典三级一区二区三区视频 | 非洲特黄一级毛片高清视频 | аⅴ资源中文在线天堂 | 久久精品一区二区三区资源网 | 国产精品一区二区av | 99成人免费视频 | 九九久久亚洲综合久久久 | 善良的嫂子3电影 | 丁香六月婷婷激情 | 天天综合天天看夜夜添狠狠玩 | 四虎影视免费在线观看 | 激情五月深爱五月 | 免费观看国产大片资源视频 | 久久久久免费 | 青草影院天堂男人久久 | 无码av免费一区二区三区试看 |