中文在线一区二区_欧美在线综合_久久久久久综合_欧美一区二区三区视频_国产免费看_国产福利精品一区

雙機(jī)熱備

1. 介紹

文章主要介紹,EasySwoole 使用雙機(jī)熱備思路實(shí)現(xiàn)代碼不中斷部署。

2. 學(xué)習(xí)案例

    1. 先部署 9501 服務(wù)
    1. 單起一個(gè)進(jìn)程,定時(shí)輪詢 Git 分支是否有新版本發(fā)布
    1. 如有新版本發(fā)布,clone 一份
    1. composer update 更新庫(kù)
    1. 啟動(dòng) 9502 服務(wù)
    1. 更改 nginx 配置為 9502 并重啟

只要有新版本發(fā)布,就輪詢上面那幾個(gè)步驟

整個(gè)過(guò)程的簡(jiǎn)單架構(gòu)圖

image.png

3. 需要提前了解的知識(shí)點(diǎn)

  1. Nginx 負(fù)載均衡和反向代理
  2. EasySwoole 自定義進(jìn)程
  3. Nginx reload 和 restart 的區(qū)別
  4. 雙機(jī)熱備

4. Nginx 配置

nginx.conf 配置文件示例

當(dāng)有新版本發(fā)布的時(shí)候 EasySwoole 自定義進(jìn)程會(huì)將 nginx.conf 的端口改為最新服務(wù)的端口

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;

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

    include servers/*;
}

es-release.conf 站點(diǎn)配置文件

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

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

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

5. EasySwoole 代碼實(shí)現(xiàn)

代碼只提供實(shí)現(xiàn)思路,并且這種腳本,最好單獨(dú)去做,比如用 shell 腳本,防止服務(wù)宕機(jī)導(dǎo)致無(wú)法正常部署代碼

創(chuàng)建自定義進(jìn)程類文件

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://m.jrrswxmm.cn
 * @document http://m.jrrswxmm.cn
 * @contact http://m.jrrswxmm.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') . '開(kāi)始檢測(cè)代碼是否更新 ===> START <=== ');
                // 檢查 Git 是否有新代碼發(fā)布
                $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('有新版本發(fā)布' . json_encode($pullResult));
                    // 新版本項(xiàng)目的目錄
                    $newVersionPath = '/Users/xxx/sites/release-' . time();

                    // 開(kāi)始 clone, 初始化代碼
                    ### 這里需要換成自己的 EasySwoole 項(xiàng)目的 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');

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

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

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

                    // 替換 Nginx 配置
                    $this->dolog('開(kāi)始替換 nginx 端口');
                    ### 這里需要換成自己服務(wù)器環(huán)境 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 服務(wù)
                    $this->dolog('重啟 nginx ');
                    $reloadNgExec = "nginx -s reload {$shellLog}";
                    $this->dolog($reloadNgExec);
                    exec($reloadNgExec);

                    // 停掉舊服務(wù)
                    $this->dolog('舊服務(wù)停掉');
                    $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('無(wú)新版本更新');
                }
            }
        });
    }
}

注冊(cè)自定義進(jìn)程

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

<?php
/**
 * This file is part of EasySwoole.
 *
 * @link http://m.jrrswxmm.cn
 * @document http://m.jrrswxmm.cn
 * @contact http://m.jrrswxmm.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)
    {
        ###### 注冊(cè) 雙機(jī)熱備服務(wù) 自定義進(jìn)程 ######
        $processConfig = new \EasySwoole\Component\Process\Config([
            'processName' => 'Es-release', // 設(shè)置 自定義進(jìn)程名稱
            'processGroup' => 'Es-release', // 設(shè)置 自定義進(jìn)程組名稱
        ]);
        \EasySwoole\Component\Process\Manager::getInstance()->addProcess(new Release($processConfig));
    }
}

6. 測(cè)試

綁定 host

127.0.0.1 easyswoole.release.com

訪問(wèn) easyswoole.release.com

image.png

查看 Nginx 配置的端口

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

發(fā)布新版本

重新 clone 一份代碼,更改內(nèi)容提交。

查看Nginx配置的端口

?  nginx cat nginx.conf | grep 950
           server    127.0.0.1:9502;
主站蜘蛛池模板: 日韩精品成人 | 欧美日韩中文在线观看 | 福利视频网址导航 | 老黄网站在线观看 | 中文在线一区二区三区 | 免费观看aaa | 黄色一级毛片免费看 | 北条麻妃在线一区二区免费播放 | 先锋av资源 | 成人影院www在线观看 | 亚洲欧美激情精品一区二区 | 高清国产一区二区三区 | 欧美怡红院视频一区二区三区 | 欧美日韩免费 | 国产高清在线精品一区二区三区 | av片免费看| 亚洲欧美综合精品久久成人 | 免费一级欧美在线观看视频 | 欧美日韩久久久 | 久久九九这里只有精品 | 国产精品免费网站 | 成人在线免费观看 | 91综合网| 高清三区 | 亚洲四区 | 免费在线观看毛片 | 精品久| 国产精品久久久久久久久久久久久 | 久热久热 | 一级全黄少妇性色生活片免费 | 亚洲第一免费播放区 | 日韩城人免费 | 中文字幕乱码亚洲精品一区 | 国产成人一级毛片 | 欧美亚洲精品在线 | 国产成人精品一区二区三区视频 | 日韩午夜电影 | 精精国产xxxx视频在线 | 国产乱视频 | 午夜成人免费视频 | 亚洲毛片网站 |