死磕nginx系列--使用upsync模塊實現負載均衡


問題描述

nginx reload是有一定損耗的,如果你使用的是長連接的話,那么當reload nginx時長連接所有的worker進程會進行優雅退出,並當該worker進程上的所有連接都釋放時,進程才真正退出。

解決辦法

對於社區版nginx目前有三個選擇方式:

  1. Tengine 的Dyups模塊。
  2. 微博的Upsync+Consul 實現動態負載均衡。
  3. OpenResty的balancer_by_lua(又拍雲使用其開源的slardar(Consul balancer_by_lua))。

本文使用upsync模塊來解決配置文件修改后,reload nginx進程造成性能下降的問題。

它的功能是拉取 consul 的后端 server 的列表,並更新 Nginx 的路由信息。此模塊不依賴於任何第三方模塊。consul 作為 Nginx 的 db,利用 consul 的 KV 服務,每個 Nginx work 進程獨立的去拉取各個 upstream 的配置,並更新各自的路由。

實戰

給nginx打補丁包

這步可以不做,如果不做,編譯的時候刪除這個模塊

git clone https://github.com/xiaokai-wang/nginx_upstream_check_module
## 打補丁包
patch -p0 < /usr/local/src/nginx_upstream_check_module-master/check_1.9.2+.patch 

下載nginx-upsync-module源碼

git clone https://github.com/weibocom/nginx-upsync-module.git

下載nginx源碼
wget 'http://nginx.org/download/nginx-1.10.1.tar.gz'
tar -xzvf nginx-1.10.1.tar.gz
cd nginx-1.10.1/
開始編譯
./configure --prefix=/data/app/nginx-1.10.1 --user=nginx --group=nginx  --with-http_ssl_module  --with-http_stub_status_module   --add-module=/usr/local/src/nginx-upsync-module-master/ --add-module=/usr/local/src/nginx_upstream_check_module-master/
make
make install

啟動consul

wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
unzip consul_0.6.4_linux_amd64.zip
./consul agent -advertise=x.x.x.x -client=0.0.0.0 -dev

創建nginx配置文件

mkdir -p /usr/local/nginx/conf/servers
/usr/local/nginx/conf/nginx.conf
events {
  worker_connections  4096;  ## Default: 1024
}

http {
    upstream test {
        # fake server otherwise ngx_http_upstream will report error when startup
        server 127.0.0.1:11111;

        # all backend server will pull from consul when startup and will delete fake server
        upsync 127.0.0.1:8500/v1/kv/upstreams/test upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
        upsync_dump_path /usr/local/nginx/conf/servers/servers_test.conf;
    }

    upstream bar {
        server 127.0.0.1:8090 weight=1 fail_timeout=10 max_fails=3;
    }

    server {
        listen 8080;

        location = /proxy_test {
            proxy_pass http://test;
        }

        location = /bar {
            proxy_pass http://bar;
        }

        location = /upstream_show {
            upstream_show;
        }

    }
}

測試

for i in `seq 3`;do mkdir html$i/test -p && echo $i >html$i/test/test.html; done;  

docker run -d -p 8001:80 -v /root/html1/:/usr/share/nginx/html nginx 
docker run -d -p 8002:80 -v /root/html2/:/usr/share/nginx/html nginx 
docker run -d -p 8003:80 -v /root/html3/:/usr/share/nginx/html nginx 

添加服務

curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8001
curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8002
curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8003

查看conf/servers/servers_test.conf 文件中是否有內容

cat conf/servers/servers_test.conf 
server 192.168.56.12:8003 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8002 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8001 weight=1 max_fails=2 fail_timeout=10s;

或者瀏覽器打開http://192.168.56.11:8080/upstream_show?test
顯示內容如下:

Upstream name: test; Backend server count: 3
        server 192.168.56.12:8003 weight=1 max_fails=2 fail_timeout=10s;
        server 192.168.56.12:8002 weight=1 max_fails=2 fail_timeout=10s;
        server 192.168.56.12:8001 weight=1 max_fails=2 fail_timeout=10s;

總結
此模塊只修改upstream 中的緩存信息,不能修改或添加其他配置

測試中遇到的問題
在添加服務時出現如下錯誤,導致服務添加不能實時進行,大約需要3分鍾左右時間。

consul日志:

2016/03/22 05:34:42 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (149.023µs) from=127.0.0.1:38853
    2016/03/22 05:34:43 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (146.759µs) from=127.0.0.1:38854
    2016/03/22 05:34:45 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (149.853µs) from=127.0.0.1:38855
    2016/03/22 05:34:46 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (111.46µs) from=127.0.0.1:38856
    2016/03/22 05:34:48 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (142.696µs) from=127.0.0.1:38857
    2016/03/22 05:34:48 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (112.089µs) from=127.0.0.1:38858
    2016/03/22 05:34:49 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (114.29µs) from=127.0.0.1:38859
    2016/03/22 05:34:50 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (148.245µs) from=127.0.0.1:38860

nginx日志

2016/03/22 05:35:09 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:09 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:10 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:10 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:11 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:11 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:13 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:13 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:13 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:13 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:14 [error] 18879#0: recv() failed (104: Connection reset by peer)

問題現象
當添加一個服務時,出現此問題,新增服務不能及時添加到負載中,不影響運行正常的服務。 此時再往consul繼續添加一個服務時,可能會導致此錯誤終止,並能成功添加當前兩條服務記錄。

幫助文檔

官方github地址
nginx_upstream_check_module


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM