這是 Nginx 學習總結的第六篇,上一篇介紹到了 Nginx 學習總結(5) —— 反向代理,本文主要演示結合 proxy
和 upstream
模塊的使用來實現 Nginx 的負載均衡。html
Nginx 官網中對 upstream
模塊的介紹:ngx_http_upstream_module
模塊用於定義可由 proxy_pass
,fastcgi_pass
,uwsgi_pass
,scgi_pass
和 memcached_pass
指令引用的服務器組。mysql
Context:http
在 VMware 上準備 3 臺服務器(centos_7_x64),分別安裝了 Nginx(1.12.0),它們可以互相 ping
通,3臺服務器 IP 分別爲:nginx
在 Web 服務器的根目錄下的 index.html 文件內容分別爲:git
<h1>Welcome to 192.168.4.221 !</h1>
<h1>Welcome to 192.168.4.222 !</h1>
在 Nginx 下配置反向代理,主要是 proxy
和 upstream
模塊的配置。咱們將反向代理服務器 C 的配置修改爲以下:github
upstream jochen { server 192.168.4.221:80; server 192.168.4.222:80; } server { listen 80; server_name localhost; charset utf-8; location / { proxy_pass http://jochen; proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
配置好以後,重啓反向代理服務器 C ,瀏覽器訪問 http://192.168.4.223
:
算法
瀏覽器刷新頁面:
sql
咱們能夠發現,訪問的內容的確是 Web 服務器 A 或 B 提供的內容,代表咱們的反向代理是配置成功了。並且,響應內容是由 Web 服務器 A、B 依次輪流提供的。segmentfault
負載均衡是反向代理技術的一種運用。客戶端訪問服務器,服務器會把請求分發給其它多個不一樣的服務器(即反向代理),從而減輕了單個服務器處理海量請求的壓力,不會出現崩潰,即如圖:
後端
在上面的配置中,咱們沒有設置 upstream
的分配方式,默認狀況下,這將採用輪詢的方式,即每一個請求按時間逐一分配到不一樣的後端服務器。若是後端服務器 down 掉,能自動剔除。而實現負載均衡的核心在於如何將請求合理地分配給不一樣的後端服務器。centos
在現實生活中,不一樣服務器的 CPU 、內存、硬盤、網絡帶寬的性能都是不一樣的,於是它們各自的處理能力各不同。須要採用某種負載均衡調度算法,來將請求合理地分配給不一樣的後端服務器,以達到最佳化資源使用、最大化吞吐率、最小化響應時間、同時避免過載的目的。
在 Nginx 中,upstream
的分配方式有 5 種,分別是:
每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器 down 掉,能自動剔除。如:
upstream jochen { server 192.168.4.221:80; server 192.168.4.222:80; }
指定輪詢概率,weight 和訪問比率成正比,用於後端服務器性能不均的狀況。如:
upstream jochen { server 192.168.4.221:80 weight=10; server 192.168.4.222:80 weight=20; }
每一個請求按訪問 ip 的 hash 結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決 session 的問題。如:
upstream jochen { server 192.168.4.221:80; server 192.168.4.222:80; ip_hash; }
按後端服務器的響應時間來分配請求,響應時間短的優先分配。這個是第三方模塊,須要額外安裝。如:
upstream jochen { server 192.168.4.221:80; server 192.168.4.222:80; fair; }
按訪問 url 的 hash 結果來分配請求,使每一個 url 定向到同一個後端服務器,後端服務器爲緩存時比較有效。這個是第三方模塊,須要額外安裝。如:
upstream jochen { server 192.168.4.221:80; server 192.168.4.222:80; hash $request_uri; hash_method crc32; }
在 upstream
模塊中,能夠經過 server
指令定義服務器的地址和其餘參數。地址能夠指定爲域名,或 IP 地址(端口可選,默認爲80),或 "unix" 爲前綴的套接字路徑。
Context: upstream
經常使用的參數有:
down
將服務器標記爲永久不可用weight
設置服務器的權重,默認狀況下爲 1backup
將服務器標記爲備份服務器。當主服務器不可用時,它將被傳遞請求max_fails
容許請求失敗的次數,默認爲 1fail_timeout
在經歷了 max_fails
次失敗後,暫停服務的時間。max_fails
能夠和 fail_timeout
一塊兒使用upstream jochen { server backend1.example.com weight=5; server 192.168.4.222:80 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; server backup1.example.com backup; }
Nginx 自身是沒有針對負載均衡後端節點健康檢查的模塊,nginx_upstream_check_module
是專門用於負載均衡健康檢查的第三方模塊,由淘寶的姚偉斌大神開發,經過它能夠用來檢測後端 server
的健康狀態。nginx_upstream_check_module
模塊會持續檢查 server
的狀態,若是某個 server
不可用,則請求就不會被轉發到該 server
上。項目地址:https://github.com/yaoweibin/... 。
下面的是一個帶負載均衡健康檢查的 nginx.conf 配置:
upstream jochen { server 192.168.4.221:80 weight=5 max_fails=2 fail_timeout=30s; server 192.168.4.222:80 weight=1 max_fails=2 fail_timeout=30s; check interval=5000 rise=2 fall=3 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; } server { listen 80; server_name localhost; charset utf-8; location / { proxy_pass http://jochen; proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /nginx-status { stub_status; access_log off; allow 192.168.4.220; deny all; } location /check-status { check_status; access_log off; allow 192.168.4.220; deny all; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
重啓 Nginx 配置生效以後,能夠看到 error.log 日誌以下信息,說明 nginx_upstream_check_module
模塊已正常運行:
2018/03/29 15:12:48 [error] 46931#46931: enable check peer: 192.168.4.221:80 2018/03/29 15:12:50 [error] 46931#46931: enable check peer: 192.168.4.222:80
同時,訪問 http://192.168.4.223/check-status
,能夠看到以下頁面:
上面配置的意思是,對 jochen 這個服務器組中的全部 server,每5秒檢測一次,請求 2 次正常則標記 server 狀態爲up,若是檢測 3 次都失敗,則標記 server 的狀態爲 down,超時時間爲1秒。
nginx_upstream_check_module
模塊的指令詳情見 https://github.com/yaoweibin/...,經常使用指令說明以下:
check
爲上游服務器添加運行情況檢查,經常使用參數以下:
interval
向後端發送的健康檢查包的間隔fall
若是連續失敗次數達到 fall_count
,服務器就被認爲是 downrise
若是連續成功次數達到 rise_count
,服務器就被認爲是 uptimeout
後端健康請求的超時時間type
健康檢查包的類型,包括 tcp、http、ajp、ssl_hello、mysql、fastcgicheck_http_send
配置 HTTP 監控檢查包發送的請求內容,爲了減小傳輸數據量,推薦採用 HEAD 方法。check_http_expect_alive
指定 HTTP 回覆的成功狀態,默認認爲 2XX 和 3XX 的狀態是健康的。參考文章: