參考:php
http://www.php230.com/weixin1456193048.html 【upsync模塊說明、性能評測】html
https://www.jianshu.com/p/76352efc5657
node
https://www.jianshu.com/p/c3fe55e6a5f2linux
說明:nginx
動態nginx負載均衡的配置,能夠經過Consul+Consul-template方式,可是這種方案有個缺點:每次發現配置變動都須要reload nginx,而reload是有必定損耗的。並且,若是你須要長鏈接支持的話,那麼當reloadnginx時長鏈接所在worker進程會進行優雅退出,並當該worker進程上的全部鏈接都釋放時,進程才真正退出(表現爲worker進程處於worker process is shutting down)。所以,若是能作到不reload就能動態更改upstream,那麼就完美了。c++
目前的開源解決方法有3種:git
一、Tengine的Dyups模塊github
二、微博的Upsync模塊+Consulweb
三、使用OpenResty的balancer_by_lua,而又拍雲使用其開源的slardar(Consul + balancer_by_lua)實現動態負載均衡。
bootstrap
這裏咱們使用的是upsync模塊+consul 來實現動態負載均衡。操做筆記以下:
consul的命令很簡單,官方文檔有詳細的樣例供參考,這裏略過。
實驗環境:
3臺centos7.3機器
cat /etc/hosts 以下:
192.168.5.71 node71
192.168.5.72 node72
192.168.5.73 node73
consul 咱們使用3節點都是server角色。若是集羣內某個節點宕機的話,集羣會自動從新選主的。
nginx-Upsync模塊:新浪微博開源的,,它的功能是拉取 consul 的後端 server 的列表,並更新 Nginx 的路由信息。且reload對nginx性能影響不多。
nginx-upsync-module模塊: https://github.com/weibocom/nginx-upsync-module
nginx版本:1.13.8
yum install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel -y
cd /root/
git clone https://github.com/weibocom/nginx-upsync-module.git
# 建議使用git clone代碼編譯,剛開始我使用release的tar.gz 編譯nginx失敗了
groupadd nginx
useradd -g nginx -s /sbin/nologin nginx
mkdir -p /var/tmp/nginx/client/
mkdir -p /usr/local/nginx
tar xf nginx-1.13.8.tar.gz
cd /root/nginx-1.13.8
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=/root/nginx-upsync-module
make && make install
echo 'export PATH=/usr/local/nginx/sbin:$PATH' >> /etc/profile
source /etc/profile
在node1上配置虛擬主機:
cat /usr/local/nginx/conf/nginx.conf 內容以下:
user nginx;
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name 192.168.5.71;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
建立網頁文件:
echo 'node71' > /usr/share/nginx/html/index.html
在node3上啓動虛擬主機:
cat /usr/local/nginx/conf/nginx.conf 內容以下:
user nginx;
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name 192.168.5.73;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
建立網頁文件:
echo 'node73' > /usr/share/nginx/html/index.html
在node2上配置虛擬主機:
此處的node2做爲LB負載均衡+代理服務器使用
cat /usr/local/nginx/conf/nginx.conf 內容以下:
user nginx;
worker_processes 1;
error_log logs/error.log notice;
pid logs/nginx.pid;
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"'
'$upstream_addr $upstream_status $upstream_response_time $request_time';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
upstream pic_backend {
# 兜底假數據
# server 192.168.5.72:82;
# upsync模塊會去consul拉取最新的upstream信息並存到本地的文件中
upsync 192.168.5.72:8500/v1/kv/upstreams/pic_backend upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
upsync_dump_path /usr/local/nginx/conf/servers/servers_pic_backend.conf;
}
# LB對外信息
server {
listen 80;
server_name 192.168.5.72;
location = / {
proxy_pass http://pic_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header real $upstream_addr;
}
location = /upstream_show {
upstream_show;
}
location = /upstream_status {
stub_status on;
access_log off;
}
}
# 兜底的後端服務器
server {
listen 82;
server_name 192.168.5.72;
location / {
root /usr/share/nginx/html82/;
index index.html index.htm;
}
}
}
建立網頁文件:
mkdir /usr/share/nginx/html82 -p
echo 'fake data in SLB_72' > /usr/share/nginx/html82/index.html
建立upsync_dump_path(consul、upsync存放upstream主機信息使用到這個目錄)
mkdir /usr/local/nginx/conf/servers/
cd /root/
mkdir /usr/local/consul/
unzip consul_1.0.0_linux_amd64.zip
mv consul /usr/local/consul/
mkdir /etc/consul.d
cd /usr/local/consul/
echo 'export PATH=/usr/local/consul/:$PATH' >> /etc/profile
source /etc/profile
node71上:
/usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node71 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.71 -client 0.0.0.0
node72上:
/usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node72 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.72 -client 0.0.0.0 -join 192.168.5.71
意思是把本節點加入到192.168.5.71這個ip的節點中
node73上:
/usr/local/consul/consul agent -server -bootstrap-expect 3 -ui -node=node73 -config-dir=/etc/consul.d --data-dir=/etc/consul.d -bind=192.168.5.73 -client 0.0.0.0 -join 192.168.5.71
意思是把本節點加入到192.168.5.71這個ip的節點中
這樣的話,就在3臺主機前臺啓動了consul程序。
能夠在任一臺主機上執行:
consul members 列出當前集羣的節點狀態
consul info 列出當前集羣的節點詳細信息 (輸出信息太多,本身運行時候看去吧)
訪問consul自帶的web界面
http://192.168.5.71/upstream_show (3個節點都開了webui,所以咱們訪問任意節點都行)
在任一節點上執行以下命令,便可添加2個key-value信息:
curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
在web界面,就可看到以下所示:
刪除的命令是:
curl -X DELETE http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
curl -X DELETE http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
調整後端服務的參數:
curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.71:80
在node1、node2、node3上都執行 /usr/local/nginx/sbin/nginx 啓動nginx服務
訪問http://192.168.5.72/upstream_show
訪問http://192.168.5.72/upstream_status
剛纔咱們在第三步的時候,執行了以下2條命令,自動在consul裏面加了2行內容。
curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.71:80
curl -X PUT -d '{"weight":10, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/pic_backend/192.168.5.73:80
咱們node2的nginx在啓動的時候,會去nginx.conf裏面配置的consul地址去尋找對應的upstream信息。同時會dump一份upstream的配置到/usr/local/nginx/conf/servers目錄下。
[root@node72 /usr/local/nginx/conf/servers ]# cat servers_pic_backend.conf
server 192.168.5.73:80 weight=10 max_fails=2 fail_timeout=10s;
server 192.168.5.71:80 weight=10 max_fails=2 fail_timeout=10s;
咱們能夠寫個curl腳本測試下,以下
for i in {1..100} ;do curl http://192.168.5.72/; done > /root/log
grep -c node71 /root/log ;grep -c node73 /root/log
能夠看到curl是輪詢請求到後端的node1和node3上去的。
或者使用for i in {1..100} ;do curl -s -I http://192.168.5.72/|tail -2 |head -1; done
若是要下線後端主機進行發佈的話,只要把down參數置爲1便可,相似以下:
curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":1}' http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
若是發佈完成並驗證後,須要上線,能夠再次把down參數置爲0:
curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
若是調整在線調整後端服務的upstream參數:
curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":0}' http://192.168.5.71:8500/v1/kv/upstreams/test/192.168.5.73:80
說明:
一、每次去拉取 consul 都會設置鏈接超時,因爲 consul 在無更新的狀況下默認會 hang 五分鐘,因此響應超時配置時間應大於五分鐘。大於五分鐘以後,consul 依舊沒有返回,便直接作超時處理。
二、因爲upsync模塊會在pull新數據時候,自動在本地存一份upstream配置的副本。所以即使咱們上面的3個consul進程所有宕掉了,nginx服務短期內也不會受到影響。只要咱們的監控完善及時將consul進程啓動便可。
此外,還可以使用nginx +consulconsul-template這種架構來控制nginx的配置
具體能夠參考:
https://www.jianshu.com/p/9976e874c099
https://www.jianshu.com/p/a4c04a3eeb57?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
https://www.cnblogs.com/MrCandy/p/7152312.html
https://github.com/hashicorp/consul-template
官方提供的nginx參考模板:https://github.com/hashicorp/consul-template/blob/master/examples/nginx.md