利用 consul+nginx-upsync 實現動態負載

13sai發表於2019-12-01

這是前一段時間學習的課程上面的,自己實際操作了一下,詳細操作及說明如下。


如果Nginx遇到大流量和高負載,修改配置檔案重啟可能並不總是那麼方便,因為恢復Nginx並過載配置會進一步增加系統負載,並很可能暫時降低效能。而一個個修改配置檔案也是很容易出錯和費時間的操作。

這時候不妨試試consul+nginx-upsync-module實現Nginx的動態負載。

nginx-upsync-module

nginx-upsync-module 提供了動態的負載均衡,它可以從consul或etcd同步upstreams,動態修改後端伺服器屬性(weight,max_fails,down…),而不需要重新載入nginx。這樣我們通過它實現平滑伸縮,而不嚴重地影響效能。

利用docker安裝

我已經基於centos7構建了一個映象 13sai/nginx-lua-upsync ,你可以使用下面的命令啟動一個容器

docker run -itd --name=nginx-upsync -p 8008:80 -p 9501:9501 -p 9502:9502 -p 9503:9503 -p 8500:8500 13sai/nginx-lua-upsync

當然,你也可以不使用docker自行搭建,新增nginx-upsync-module模組可以參考nginx模組lua模組

進入容器配置

docker exec -it nginx-upsync /bin/bash

cd /usr/local/nginx/conf

echo "server host.docker.internal:9501 weight=1 fail_timeout=10 max_fails=3;" >> servers.conf

vi nginx.conf

 #nginx.conf 主要配置
 ...

 upstream 13sai{
    upsync 192.168.65.2:8500/v1/kv/upstreams/test-server upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
    upsync_dump_path /usr/local/nginx/conf/servers.conf;
    include /usr/local/nginx/conf/servers.conf;
}

server {
    listen       80;

    location / {
        proxy_pass http://13sai;
    }

    ...

}

...

upsync語法說明

語法:syntax: upsync $consul/etcd.api.com:$port/v1/kv/upstreams/$upstream_name/ [upsync_type=consul/etcd] [upsync_interval=second/minutes] [upsync_timeout=second/minutes] [strong_dependency=off/on]
預設值:無,如果省略引數,則預設引數為upsync_interval = 5s upsync_timeout = 6m strong_dependency = off
上下文:上游
描述:從 consul/etcd 中拉取upstreams

upsync 定義從consul/etcd拉取最新的upstream資訊並存到本地的操作
upsync_timeout 定義從consul/etcd拉取配置的超時時間
upsync_interval 定義從consul/etc拉取配置的間隔時間
upsync_type 定義使用配置服務型別
strong_dependency 啟動時是否強制依賴配置伺服器,如果配置為on,則拉取失敗,nginx同樣會啟用失敗
upsync_dump_path 定義從consul/etcd拉取配置後持久化到的本地的檔案路徑,這樣即使 consul/etcd出問題了,本地同樣會有備份檔案

注意下面這個檔案必須要有,檔案路徑和名稱可以自定義,nginx-upsync-module會將負載資訊快取到此檔案,否則Nginx啟動會報錯。

#servers.conf,192.168.x.xxx是我的宿主機ip
server 192.168.x.xxx:9501 weight=20 max_fails=1 fail_timeout=5s;

重啟nginx

/usr/local/nginx/sbin/nginx -t

/usr/local/nginx/sbin/nginx -s reload

這裡雖然我們還未啟動consul,但沒有什麼影響,upsync會去拉取,也必然會失敗,servers.conf就不會更新,Nginx的error日誌會有資訊。

利用swoole啟動3個http服務

// 可啟動3個server,埠分別為9501,9502,9503,輸出也做對應修改
$http = new Swoole\Http\Server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) {
    $response->end("9501");
});

consul安裝

這裡consul只做一個kv儲存,我自己也是第一次用,就不去做過多介紹了。

下載地址

解壓到你需要的目錄,主要也就是一個consul可執行檔案。(這裡我裝在我的電腦,而不是剛才的docker容器)

命令可看文件:Consul 簡介和快速入門

啟動:

nohup ./consul agent -dev &

為了方便,我們也沒有啟動叢集,生產環境建議使用consul叢集。

UI檢視

http://127.0.0.1:8500/

檢視節點

./consul members

curl 127.0.0.1:8500/v1/catalog/nodes

檢視kv值

curl -v http://127.0.0.1:8500/v1/kv/\?recurse

consul

新增

curl -X PUT -d '{"weight":20,"max_fails":2,"fail_timeout":5}' http://127.0.0.1:8500/v1/kv/upstreams/test...

此處192.168.x.xxx是因為我建立的docker容器的宿主機ip。

刪除

curl -X DELETE http://127.0.0.1:8500/v1/kv/upstreams/test...


我們可以通過新增和刪除來測試,檢視http://127.0.0.1:8008/來檢視輸出,也可以看看Nginx裡的配置檔案servers.conf,你會看到你操作consul,會動態改變Nginx的upstream,這樣就實現了Nginx的動態擴容。


對consul和docker的學習還不夠深入,文中如有錯誤,歡迎指正交流。

Nginx 相關文章:


技術文章也釋出在自己的公眾號【愛好歷史的程式設計師】,歡迎掃碼關注,謝謝!

愛好歷史的程式設計師

分享開發知識,歡迎交流。

相關文章