http upstream配置參數:
ngx_http_upstream_module模塊
將多個服務器定義成服務器組,而由proxy_pass, fastcgi_pass等指令進行引用
upstream name { ... }
定義后端服務器組,會引入一個新的上下文;
默認調度算法是wrr:
Context: http upstream httpdsrvs { server ... server... ... }
server address [parameters];
#配置一個后端web服務器,配置在upstream內,至少要有一個server服務器配置。
server支持的parameters如下:
weight=number #設置權重,默認為1。 max_conns=number #給當前server設置最大活動鏈接數,默認為0表示沒有限制。 max_fails=number #對后端服務器連續監測失敗多少次就標記為不可用。 fail_timeout=time #對后端服務器的單次監測超時時間,默認為10秒。 backup #設置為備份服務器,當所有服務器不可用時將重新啟用次服務器。 down #標記為down狀態。 resolve #當server定義的是主機名的時候,當A記錄發生變化會自動應用新IP而不用重啟Nginx。
實現nginx反向代理調度功能:
A主機:192.168.37.27 nginx服務器
B主機:192.168.37.17 httpd服務器
C主機:192.168.37.37 httpd服務器
nginx服務器上配置文件:
1、修改nginx配置文件,關聯后端httpd服務,進行調度。
[root@centos27site1]#vim /etc/nginx/nginx.conf upstream websrv{ server 192.168.37.17:80; server 192.168.37.37:80; }
vim /etc/nginx/conf.d/test.conf
server { listen 80; server_name www.magedu.net; root /data/site1; index index.html; location / { proxy_pass http://websrv; } }
在兩個后端httpd后端服務創建文件
[root@centos17~]#echo 192.168.37.17 > /var/www/html/index.html [root@centos17~]#systemctl start httpd [root@centos37site1]#systemctl start httpd [root@centos37site1]#echo 192.168.37.37 > /var/www/html/index.html
在客戶端進行調度測試
[root@centos7~]#while true;do curl www.magedu.net;sleep 0.5;done 192.168.37.17 192.168.37.37 192.168.37.17 192.168.37.37 192.168.37.17
實現宕機功能:
修改nginx主配置文件即可,在監聽的80端口后面加上down,就會將此服務器進行宕機:vim /etc/nginx/nginx.conf
http { upstream websrv{ server 192.168.37.17:80; server 192.168.37.37:80 down; 加入down,就會將此主機進行宕機處理。 }
在客戶端進行測試效果,此時nginx很巧妙的只調度17的主機,不會在顯示37宕機的效果,可以對后端服務器進行健康檢查。
[root@centos7~]#while true;do curl www.magedu.net;sleep 0.5;done 192.168.37.17 192.168.37.17 192.168.37.17
實現道歉功能:
將nginx服務器端的配置文件進行修改:vim /etc/nginx/nginx.conf,80端口被占用,最好不要指定80端口。
upstream websrv{ server 192.168.37.17:80; server 192.168.37.37:80; server 127.0.0.1:8080 backup; }
在vim /etc/nginx/conf.d/test.conf配置文件中修改配置文件,當后端httpd都宕機之后,就會顯示/data/site2里邊的文件,作為道歉顯示。
server { listen 8080; #server_name www.magedu.org; root /data/site2/; ssl_certificate /etc/nginx/ssl/magedu.org.crt; ssl_certificate_key /etc/nginx/ssl/magedu.org.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; access_log /var/log/nginx/magedu_org.access_json.log main; valid_referers none block server_names *.magedu.com ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403 "Forbidden Access"; } }
在nginx服務端的data/site2目錄下新建一個html文件。
[root@centos27site1]#mkdir /data/site2 [root@centos27site1]#echo /data/site2/test.html > /data/site2/index.html
將httpd兩個后端服務都停掉。
[root@centos37site1]#systemctl stop httpd
在客戶端進行測試效果,由於后端服務器都宕機,此時就會顯示nginx宕機道歉的文件信息。
[root@centos7~]#while true;do curl www.magedu.net;sleep 0.5;done /data/site2/test.html /data/site2/test.html
調度算法
ip_hash 源地址hash調度方法,基於的客戶端的remote_addr(源地址)做hash計算,以實現會話保持。 least_conn 最少連接調度算法,當server擁有不同的權重時其為wlc,當所有后端主機連接數相同時,則使用wrr,適用於長連接,調度到最少連接的后端服務器上。 hash key [consistent] 基於指定的key的hash表來實現對請求的調度,此處的key可以直接文本、變量或二者組合。 作用:將請求分類,同一類請求將發往同一個upstream server,使用consistent參數,將使用ketama一致性hash算法,適用於后端是Cache服務器(如varnish)時使用。所謂取模運算,就是計算兩個數相除之后的余數,比如10%7=3, 7%4=3 hash $request_uri consistent; #基於用戶請求的uri做hash,一致性hash算法 hash $remote_addr; hash $cookie_name; #key為name的cookie keepalive 連接數N; 為每個worker進程保留的空閑的長連接數量,可節約nginx端口,並減少連接管理的消耗
一致性hash算法
原理:對於下圖來看,節點數越少,越容易出現節點在哈希環上的分布不均勻,導致各節點映射的對象數量嚴重不均衡(數據傾斜);相反,節點數越多越密集,數據在哈希環上的分布就越均勻。
設計哈希函數 Hash(key),要求取值范圍為 [0, 2^32)
在對IP地址進行hash運算的結果進行取模(2^32),針對每個全服務器的權重不同,都將IP地址進行hash算法運算,然后進行取模(2^32)。
原理詮釋:
varnish 1(權重) hash(192.168.37.37)%2^32
varnish 2(權重) hash(192.168.37.47+random1)%2^32 hash(192.168.37.47+random2)%2^32 權重有兩個,對IP地址進行兩次hash運算。
varnish 3(權重) hash(192.168.37.57+random1)%2^32 hash(192.168.37.57+random2)%2^32 hash(192.168.37.57+random3)%2^32 權重有三個,就對IP地址進行三次hash運算。
以上展示,由於在hash環上只有六個隨機環,有可能分部在一起,會導致分布不均勻,此時有可能就只有外部兩個nginx服務器在工作,中間的四個環不會工作,造成兩個環負荷過大。
解決辦法:在保持權重占比的情況下,可以將三個varnish的權重分別乘以1000,如1*1000、2*1000、3*1000,此時相對的權重占比不變,環的數量增加,會將環的數量增加,不會導致數據傾斜現象,解決了不均勻的問題。
解決不均勻的代碼:hash $request_uri consistent;
實現sessionid固定保證訪問一個網址
1、在nginx服務器修改主配置文件
[root@centos27~]#vim /etc/nginx/nginx.conf upstream websrv{ server 192.168.37.17:80; server 192.168.37.37:80; hash $cookie_sessionid; }
在include指定的配置文件中添加要調用的后端httpd服務的IP地址。
[root@centos27~]#vim /etc/nginx/conf.d/test.conf server { listen 80; server_name www.magedu.net; root /data/site1; index index.html; location / { proxy_pass http://websrv; } }
2、在客戶端進行測試驗證效果,說明sessionid固定后,保證固定訪問一個網址。
實現工作於傳輸層的反代理或調度器(用法不多)
ngx_stream_core_module模塊
模擬反代基於tcp或udp的服務連接,即工作於傳輸層的反代或調度器
stream { ... }
定義stream相關的服務;Context:main
示例:
stream { upstream mysqlsrvs { server 192.168.8.2:3306; server 192.168.8.3:3306; least_conn; } server { listen 10.1.0.6:3306; proxy_pass mysqlsrvs; } }
各參數含義:
ngx_stream_proxy_module模塊 可實現代理基於TCP,UDP (1.9.13), UNIX-domain sockets的數據流 proxy_pass address; 指定后端服務器地址 proxy_timeout timeout; 無數據傳輸時,保持連接狀態的超時時長 默認為10m proxy_connect_timeout time; 設置nginx與被代理的服務器嘗試建立連接的超時時長 默認為60s
1、在nginx服務器主配置文件中添加TCP和UDP協議。
[root@centos27~]#vim /etc/nginx/nginx.conf stream { upstream mysqlsrvs { server 192.168.37.17:3306; mysql1數據庫 server 192.168.37.37:3306; mysql2數據庫 least_conn; } server { listen 192.168.37.27:3306; nginx服務器 proxy_pass mysqlsrvs; } }
2、在兩個mysql數據庫創建相同用戶賬號及數據庫,便於測試驗證
[root@centos17~]#yum install mariadb-server [root@centos17~]#systemctl start mariadb [root@centos17~]#mysql -e "grant all on *.* to test@'192.168.37.%' identified by 'centos'" [root@centos17~]#mysql -e "create database db17" 17數據庫 [root@centos37~]#mysql -e "grant all on *.* to test@'192.168.37.%' identified by 'centos' " [root@centos37~]#mysql -e "create database db37" 37數據庫
3、在mysql客戶端進行測試驗證反向代理效果,每次訪問的數據庫不一定一樣。
tcp負載均衡配置參數
stream { #定義stream upstream backend { #定義后端服務器 hash $remote_addr consistent; #定義調度算法 server backend1.example.com:12345 weight=5; #定義具體server server 127.0.0.1:12345 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; } upstream dns { #定義后端服務器 server 192.168.0.1:53535; #定義具體server server dns.example.com:53; } server { #定義server listen 12345; #監聽IP:PORT proxy_connect_timeout 1s; #連接超時時間 proxy_timeout 3s; #轉發超時時間 proxy_pass backend; #轉發到具體服務器組 } server { listen 127.0.0.1:53 udp reuseport; proxy_timeout 20s; proxy_pass dns; } server { listen [::1]:12345; proxy_pass unix:/tmp/stream.socket; } }