本文將要討論以下內(nèi)容
- 正向代理與反向代理的基本概念
- Nginx正向代理服務(wù)的配置指令、Nginx反向代理服務(wù)的配置指令
- Nginx反向代理服務(wù)器的應(yīng)用——負(fù)載均衡、故障轉(zhuǎn)移
- 案例分析
?
一. 正向代理與反向代理的概念
正向代理的概念
局域網(wǎng)內(nèi)的機(jī)器借助代理服務(wù)訪問(wèn)局域網(wǎng)外的網(wǎng)站,此代理服務(wù)器提供的服務(wù)就為正向代理服務(wù)。
作用
- 主要是為了增強(qiáng)局域網(wǎng)內(nèi)部網(wǎng)絡(luò)的安全性,使得網(wǎng)外的威脅因素不容易影響到網(wǎng)內(nèi),這里代理服務(wù)器起到了一部分防火墻的功能。
- 利用代理服務(wù)器也可以對(duì)局域網(wǎng)訪問(wèn)外網(wǎng)進(jìn)行必要的監(jiān)控和管理。
正向代理服務(wù)器不支持外部對(duì)內(nèi)部網(wǎng)絡(luò)的訪問(wèn)請(qǐng)求,即圖的箭頭方向不能反過(guò)來(lái)。
?
反向代理的概念
如果局域網(wǎng)向Internet提供資源,讓Internet上的其他用戶可以訪問(wèn)局域網(wǎng)內(nèi)的資源,此代理服務(wù)器提供的服務(wù)就叫做反向代理(Reverse Proxy)服務(wù)。
小結(jié)
正向代理服務(wù)器用來(lái)讓局域網(wǎng)客戶機(jī)接入外網(wǎng)以訪問(wèn)外網(wǎng)資源,反向代理服務(wù)器用來(lái)讓外網(wǎng)的客戶端接入局域網(wǎng)中的站點(diǎn)以訪問(wèn)站點(diǎn)中的資源。
?
在正向代理服務(wù)器中,我們的角色是客戶端,目的是要訪問(wèn)外網(wǎng)的資源;在反向代理服務(wù)器中,我們的角色是站點(diǎn),目的是把站點(diǎn)的資源發(fā)布出去讓其他客戶端能夠訪問(wèn)。
?
二. Nginx服務(wù)器的正向代理服務(wù)
1. Nginx服務(wù)器正向代理服務(wù)的配置的3個(gè)指令
1.1. resolver指令
該指令用于指定DNS服務(wù)器的IP地址。DNS服務(wù)器的主要工作是進(jìn)行域名解析,將域名映射為對(duì)應(yīng)的IP地址。
resolver address ... [valid=time];
■ address,DNS服務(wù)器的IP地址。如果不指定端口號(hào),默認(rèn)使用53端口。
■ time,設(shè)置數(shù)據(jù)包在網(wǎng)絡(luò)中的有效時(shí)間。
出現(xiàn)該指令的主要原因是,在訪問(wèn)站點(diǎn)時(shí),有很多情況使得數(shù)據(jù)包在一定時(shí)間內(nèi)不能被傳遞到目的地,但是又不能讓該數(shù)據(jù)包無(wú)期限地存在,于是就需要設(shè)定一段時(shí)間,當(dāng)數(shù)據(jù)包**在這段時(shí)間內(nèi)沒(méi)有到達(dá)目的地,就會(huì)被丟棄**,然后發(fā)送者會(huì)接收到一個(gè)消息,并決定是否要重發(fā)該數(shù)據(jù)包。
使用該指令的一個(gè)例子如下:
resolver 127.0.0.1 [::1]:5353 valid=30s;
?
1.2. resolver_timeout指令
該指令用于設(shè)置DNS服務(wù)器域名解析超時(shí)時(shí)間,語(yǔ)法結(jié)構(gòu)為:
resolver_timeout time;
?
1.3. proxy_pass指令
該指令用于設(shè)置代理服務(wù)器的協(xié)議和地址,它不僅僅用于Nginx服務(wù)器的代理服務(wù),更主要的是應(yīng)用于反向代理服務(wù)。該指令的語(yǔ)法結(jié)構(gòu)為:
proxy_pass URL;
其中,URL即為設(shè)置的代理服務(wù)器協(xié)議和地址。在代理服務(wù)配置中,該指令配置為
proxy_pass http://$http_host$request_uri;
其中,代理服務(wù)器協(xié)議設(shè)置為HTTP,$http_host 和 $request_uri兩個(gè)變量是Nginx配置支持的用于自動(dòng)獲取主機(jī)和URI的變量。
?
2. Nginx服務(wù)器正向代理服務(wù)的使用
…
server
{
resolver 8.8.8.8;
listen 82;
location /
{
proxy_pass http://$http_host$request_uri;
}
}
…
- 設(shè)置DNS服務(wù)器地址為8.8.8.8,使用默認(rèn)的53端口作為DNS服務(wù)器的服務(wù)端口
- 代理服務(wù)的監(jiān)聽端口設(shè)置為82端口,Nginx服務(wù)器接收到的所有請(qǐng)求都由location塊進(jìn)行過(guò)濾處理。
- resolver指令是必需的,如果沒(méi)有該指令,Nginx服務(wù)器無(wú)法處理接收到的域名。
- 注意:Nginx服務(wù)器的代理服務(wù)器不支持正向代理HTTPS站點(diǎn)。
?
三. Nginx服務(wù)器的反向代理服務(wù)
Nginx服務(wù)器提供的反向代理服務(wù)能夠同時(shí)接收的客戶端連接的計(jì)算方法為:
worker_processes * worker_connections / 4
配置Nginx服務(wù)器反向代理用到的指令配置在Nginx配置文件的http塊、server塊或者location塊中,一般是單獨(dú)配置一個(gè)server塊用來(lái)設(shè)置反向代理服務(wù)。這些指令主要由ngx_http_proxy_module模塊進(jìn)行解析和處理。該模塊是Nginx服務(wù)器的標(biāo)準(zhǔn)HTTP模塊。
?
1. 反向代理的基本指令
本小節(jié)涉及的指令比較重要,是為客戶端提供正常Web服務(wù)的基礎(chǔ),大家應(yīng)該熟練掌握,尤其是proxy_pass指令,在實(shí)際應(yīng)用過(guò)程中需要注意一些配置細(xì)節(jié),需要小心使用。
1.1. proxy_pass指令
1. 基礎(chǔ)用法
該指令用來(lái)設(shè)置被代理服務(wù)器的地址,可以是主機(jī)名稱、IP地址加端口號(hào)等形式。其語(yǔ)法結(jié)構(gòu)為:
proxy_pass URL;
其中,URL為要設(shè)置的被代理服務(wù)器的地址:
- 包含傳輸協(xié)議、主機(jī)名稱/IP地址加端口號(hào)、URI等要素。
- 傳輸協(xié)議通常是“http”或者“https://”。
- 指令同時(shí)還接受以“unix”開始的UNIX-domain套接字路徑。
proxy_pass http://www.myweb.name/uri;
proxy_pass http://localhost:8000/uri/;
proxy_pass http://unix:8000/uri/;
?
2. 配置一組服務(wù)器
如果被代理服務(wù)器是一組服務(wù)器的話,可以使用upstream指令配置后端服務(wù)器組。
…
#配置后端服務(wù)器組
upstream proxy_svrs
{
server http://192.168.1.1:8001/uri/;
server http://192.168.1.2:8001/uri/;
server http://192.168.1.3:8001/uri/;
}
server
{
…
listen 80;
server_name www.myweb.name;
location /
{
proxy_pass proxy_svrs; #使用服務(wù)器組的名稱
}
}
在組內(nèi)的各個(gè)服務(wù)器中都指明了傳輸協(xié)議“http://”,而在proxy_pass指令中就不需要指明了。
?
3. URI問(wèn)題
如果URL中不包含URI,Nginx服務(wù)器不會(huì)改變?cè)刂返腢RI;但是如果包含了URI,Nginx服務(wù)器將會(huì)使用新的URI替代原來(lái)的URI。
proxy_pass中不含有URI
#如果客戶端使用http://www.myweb.name:80/server發(fā)起請(qǐng)求,該請(qǐng)求
#被配置中顯示的location塊進(jìn)行處理,由于proxy_pass指令的URL變量不
#含有URI,所以轉(zhuǎn)向的地址為“http://192.168.1.1:80/server。
…
server
{
…
listen 80;
server_name www.myweb.name;
location /server/
{
…
proxy_pass http://192.168.1.1;
}
}
proxy_pass中含有URI
#如果客戶端仍然使用“http://www. myweb.name/server/”發(fā)起請(qǐng)求,#Nginx服務(wù)器將會(huì)把地址轉(zhuǎn)向“http://192.168.1.1/loc/”。
…
server
{
…
listen 80;
server_name www.myweb.name;
location /server/
{
…
proxy_pass http://192.168.1.1/loc/;
}
}
小結(jié):在使用proxy_pass指令時(shí),如果不想改變?cè)刂分械腢RI,就不要在URL變量中配置URI。
?
proxy_pass的URL末尾是否加斜杠“/”
#配置1: proxy_pass http://192.168.1.1; #不包含uri
#配置2: proxy_pass http://192.168.1.1/; #包含了uri:/
在該配置中,location塊使用“/”作為uri的值來(lái)匹配不包含URI的客戶端請(qǐng)求。
# 由于請(qǐng)求URL中不包含URI,因此配置1和配置2的效果是一樣的。
# 配置2:
# 因?yàn)楦鶕?jù)替換邏輯:http://www.myweb.name/index.htm 請(qǐng)求的/,會(huì)被替換為/,相當(dāng)于沒(méi)有替換。
…
server
{
…
listen 80;
server_name www.myweb.name;
#注意location的uri變量
location /
{
…
#配置1: proxy_pass http://192.168.1.1;
#配置2: proxy_pass http://192.168.1.1/;
}
}
# 請(qǐng)求:http://www.myweb.name/server/index.htm
#使用配置1:因?yàn)閜roxy_pass沒(méi)有uri,所以客戶端請(qǐng)求uri不會(huì)被替換
#使用配置2:proxy_pass有uri,客戶端請(qǐng)求的uri會(huì)將(被location中)/server/替換為(proxy_pass的uri)/,轉(zhuǎn)向的URL為“http://192.168.1.1/index.htm。
…
server
{
…
listen 80;
server_name www.myweb.name;
location /server/ #注意location的uri變量
{
…
#配置1: proxy_pass http://192.168.1.1;
#配置2: proxy_pass http://192.168.1.1/;
}
}
?
1.2. proxy_set_header指令
該指令可以更改(ing)Nginx服務(wù)器接收到的客戶端請(qǐng)求的請(qǐng)求頭信息,然后將新的請(qǐng)求頭發(fā)送給被代理的服務(wù)器。其語(yǔ)法結(jié)構(gòu)為:
proxy_set_header field value;
■ field,要更改的信息所在的頭域。
■ value,更改的值,支持使用文本、變量或者變量的組合。
?
什么情況下會(huì)導(dǎo)致:ing
通過(guò)httpclient請(qǐng)求到nginx時(shí),請(qǐng)求的header出現(xiàn)了丟失的情況?
?
1.3. proxy_ignore_headers指令
通過(guò)使用這個(gè)指令,可以控制哪些響應(yīng)頭部不會(huì)被傳遞給客戶端,從而影響到客戶端接收到的響應(yīng)信息。
proxy_ignore_headers field ...;
# 其中,field為要設(shè)置的HTTP響應(yīng)頭的頭域,例如“X-Accel-Redirect”、
#“X-Accel-Expires”、“Expires”、“Cache-Control”或“Set-Cookie”等。
例如,想要代理服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求時(shí)忽略掉 Set-Cookie
和 Cache-Control
這兩個(gè)響應(yīng)頭部,可以這樣配置:
location / {
proxy_pass http://backend_server;
proxy_ignore_headers Set-Cookie Cache-Control;
}
?
1.4. proxy_timeout
nginx官網(wǎng) - proxy_timeout
(在客戶端或代理服務(wù)器)兩個(gè)成功連續(xù)的讀(或?qū)懀┎僮髦g如果超過(guò)timeout時(shí)間沒(méi)有數(shù)據(jù)傳輸,鏈接將關(guān)閉。
以下是 proxy_timeout 的基本語(yǔ)法:
proxy_timeout timeout;
#1.timeout: 指定的超時(shí)時(shí)間,以秒為單位??梢允钦麛?shù)或者帶有小數(shù)點(diǎn)的浮點(diǎn)數(shù)。
例如,設(shè)置代理請(qǐng)求的超時(shí)時(shí)間為 5 秒:
location / {
proxy_pass http://backend_server;
proxy_timeout 5s;
}
?
1.5. proxy_connect_timeout
用于設(shè)置代理與后端服務(wù)器建立連接時(shí)允許的最大時(shí)間。
如果在指定的時(shí)間內(nèi)未能成功建立連接,Nginx 將終止連接并返回適當(dāng)?shù)腻e(cuò)誤。
例如,設(shè)置代理連接建立的超時(shí)時(shí)間為 3 秒:
location / {
proxy_pass http://backend_server;
proxy_connect_timeout 3s;
}
?
四. Nginx服務(wù)器的負(fù)載均衡
Nginx服務(wù)器實(shí)現(xiàn)負(fù)載均衡,主要使用的配置是proxy_pass指令和upsteam指令。
1. nginx的upstream負(fù)載均衡方式
方式 | 解釋 |
---|---|
輪詢 | 默認(rèn)方式 |
weight | 權(quán)重方式 |
ip_hash | 依據(jù)ip分配方式 |
least_conn | 最少連接方式 |
1.1. 輪詢(默認(rèn))
每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器down掉,能自動(dòng)剔除。
注意:
- 在輪詢中,如果服務(wù)器down掉了,會(huì)自動(dòng)剔除該服務(wù)器。
- 缺省配置就是輪詢策略。
- 此策略適合服務(wù)器配置相當(dāng),無(wú)狀態(tài)且短平快的服務(wù)使用。
?
1.2. weight
weight 代表權(quán)重,默認(rèn)為1,weight和訪問(wèn)比率成正比,用于后端服務(wù)器性能不均的情況。
upstream backServer {
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
在該例子中,
- weight參數(shù)用于指定輪詢幾率,weight的默認(rèn)值為1
- weight的數(shù)值與訪問(wèn)比率成正比,比如Tomcat 7.0被訪問(wèn)的幾率為其他服務(wù)器的兩倍。
注意:
- 權(quán)重越高分配到需要處理的請(qǐng)求越多。
- 此策略可以與least_conn和ip_hash結(jié)合使用。
- 此策略比較適合服務(wù)器的硬件配置差別比較大的情況。
?
1.3. ip_hash
ngx_http_upstream_module#ip_hash
每個(gè)請(qǐng)求按訪問(wèn)ip的hash結(jié)果分配,這樣每個(gè)訪客固定訪問(wèn)一個(gè)后端服務(wù)器,可以解決session的問(wèn)題。
不管刷新多少遍,始終訪問(wèn)的是同一臺(tái)tomcat服務(wù)器,但當(dāng)ip_hash到的機(jī)器掛掉時(shí),會(huì)在剩余的機(jī)器中會(huì)重新ip_hash選定機(jī)器。
upstream backServer{
ip_hash;
server 192.168.203.14:88;
server 192.168.203.15:80;
}
注意:
- 在nginx版本1.3.1之前,不能在ip_hash中使用權(quán)重(weight)。
- ip_hash不能與backup同時(shí)使用。
- 此策略適合有狀態(tài)服務(wù),比如session。
- 當(dāng)有服務(wù)器需要剔除,必須手動(dòng)down掉(這樣不利于更新和故障時(shí)候的響應(yīng))
?
1.4. 最少連接least_conn
把請(qǐng)求轉(zhuǎn)發(fā)給連接數(shù)較少的后端服務(wù)器。輪詢算法是把請(qǐng)求平均的轉(zhuǎn)發(fā)給各個(gè)后端,使它們的負(fù)載大致相同;但是,有些請(qǐng)求占用的時(shí)間很長(zhǎng),會(huì)導(dǎo)致其所在的后端負(fù)載較高。這種情況下,least_conn這種方式就可以達(dá)到更好的負(fù)載均衡效果。
upstream backServer{
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:9090;
}
注意:此負(fù)載均衡策略適合請(qǐng)求處理時(shí)間長(zhǎng)短不一造成服務(wù)器過(guò)載的情況。
?
3. 負(fù)載均衡常見參數(shù)
參數(shù) | 說(shuō)明 |
---|---|
fail_timeout | 與max_fails結(jié)合使用。 |
max_fails | 設(shè)置在fail_timeout參數(shù)設(shè)置的時(shí)間內(nèi)最大失敗次數(shù),如果在這個(gè)時(shí)間內(nèi),所有針對(duì)該服務(wù)器的請(qǐng)求都失敗了,那么認(rèn)為該服務(wù)器會(huì)被認(rèn)為是停機(jī)了。 |
fail_time | 服務(wù)器會(huì)被認(rèn)為停機(jī)的時(shí)間長(zhǎng)度,默認(rèn)為10s。 |
backup | 標(biāo)記該服務(wù)器為備用服務(wù)器。當(dāng)主服務(wù)器停止時(shí),請(qǐng)求會(huì)被發(fā)送到它這里。 |
down | 標(biāo)記服務(wù)器永久停機(jī)了。 |
4. 實(shí)現(xiàn)例子
4.1. 例子1:輪詢
例子實(shí)現(xiàn)功能
- backend服務(wù)器組中所有服務(wù)器訪問(wèn)優(yōu)先級(jí)由weight設(shè)置。
- 所有訪問(wèn)www.myweb.name(由server_name配置進(jìn)行匹配)的請(qǐng)求都會(huì)在backend服務(wù)器組中實(shí)現(xiàn)負(fù)載均衡。
…
#配置后端服務(wù)器組
upstream backend
{
server 192.168.1.2:80 weight=5;
server 192.168.1.3:80 weight=2;
#默認(rèn)weight=1
server 192.168.1.4:80;
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
…
}
…
}
訪問(wèn)過(guò)程說(shuō)明
當(dāng)有訪問(wèn)(server_name設(shè)置的)www.myweb.name的請(qǐng)求時(shí),nginx會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到backend(通過(guò)upstream設(shè)置的server列表,根據(jù)輪詢+權(quán)重選出一臺(tái))服務(wù)器來(lái)處理,處理后返回給客戶端response。
?
4.2. 例子2:對(duì)特定資源實(shí)現(xiàn)負(fù)載均衡
根據(jù)相同域名的不同URI的請(qǐng)求前綴請(qǐng)求特定資源,實(shí)現(xiàn)負(fù)載均衡。
… #其他配置
#配置后端服務(wù)器組1
upstream videobackend
{
server 192.168.1.2:80;
server 192.168.1.3:80;
server 192.168.1.4:80;
}
#配置后端服務(wù)器組2
upstream filebackend
{
server 192.168.1.5:80;
server 192.168.1.6:80;
server 192.168.1.7:80;
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
# location用于接收來(lái)自server:www.myweb.name的請(qǐng)求,并根據(jù)不同的uri前綴,將請(qǐng)求轉(zhuǎn)發(fā)到不同的后端中
#使用后端服務(wù)器組1
location /video/ {
proxy_pass http://videobackend;
proxy_set_header Host $host;
…
}
#使用后端服務(wù)器組2
location /file/ {
proxy_pass http://filebackend;
# 設(shè)置header 保留客戶端的真實(shí)信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
…
}
…
}
?
4.3. 例子3:對(duì)不同域名實(shí)現(xiàn)負(fù)載均衡
根據(jù)不同的域名+端口定位到請(qǐng)求的資源
…
upstream bbsbackend
{
server 192.168.1.2:80 weight=2;
server 192.168.1.3:80 weight=2;
server 192.168.1.4:80;
}
upstream homebackend
{
server 192.168.1.4:80;
server 192.168.1.5:80;
server 192.168.1.6:80;
}
# 開始配置server 1
server
{
listen 80;
server_name home.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://homebackend;
proxy_set_header Host $host;
…
}
…
}
# 開始配置server 2
server
{
listen 81;
server_name bbs.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://bbsbackend;
proxy_set_header Host $host;
…
}
…
}
?
五. nginx實(shí)現(xiàn)故障轉(zhuǎn)移
1. 基本邏輯
1.1. nginx判斷節(jié)點(diǎn)失效的邏輯
- Nginx 默認(rèn)判斷失敗節(jié)點(diǎn)狀態(tài)以connect refuse和timeout狀態(tài)為準(zhǔn),不以HTTP錯(cuò)誤狀態(tài)進(jìn)行判斷失敗,因?yàn)镠TTP只要能返回狀態(tài)說(shuō)明該節(jié)點(diǎn)還可以正常連接,所以nginx判斷其還是存活狀態(tài);
- 通過(guò)添加了proxy_next_upstream指令設(shè)置對(duì)404、502、503、504、500和time out等錯(cuò)誤進(jìn)行轉(zhuǎn)到備機(jī)處理,在next_upstream過(guò)程中,會(huì)對(duì)fails進(jìn)行累加,如果備用機(jī)處理還是錯(cuò)誤則直接返回錯(cuò)誤信息(但404不進(jìn)行記錄到錯(cuò)誤數(shù),如果不配置錯(cuò)誤狀態(tài)也不對(duì)其進(jìn)行錯(cuò)誤狀態(tài)記錄),
綜述,nginx記錄錯(cuò)誤數(shù)量只記錄timeout 、connect refuse、502、500、503、504這6種狀態(tài),timeout和connect refuse是永遠(yuǎn)被記錄錯(cuò)誤狀態(tài),而502、500、503、504只有在配置proxy_next_upstream后nginx才會(huì)記錄這4種HTTP錯(cuò)誤到fails中,當(dāng)fails大于等于max_fails時(shí),則該節(jié)點(diǎn)失效;
?
1.2. nginx處理節(jié)點(diǎn)失效和恢復(fù)的邏輯
參數(shù)設(shè)置:
nginx可以通過(guò)設(shè)置
- max_fails(最大嘗試失敗次數(shù))
- fail_timeout(失效時(shí)間,在到達(dá)最大嘗試失敗次數(shù)后,在fail_timeout的時(shí)間范圍內(nèi)節(jié)點(diǎn)被置為失效,除非所有節(jié)點(diǎn)都失效,否則該時(shí)間內(nèi),節(jié)點(diǎn)不進(jìn)行恢復(fù))
對(duì)節(jié)點(diǎn)失敗的嘗試次數(shù)和失效時(shí)間進(jìn)行設(shè)置。
節(jié)點(diǎn)失效和恢復(fù)邏輯:
a. 當(dāng)超過(guò)最大嘗試次數(shù)或失效時(shí)間未超過(guò)配置失效時(shí)間,則nginx會(huì)對(duì)節(jié)點(diǎn)狀會(huì)置為失效狀態(tài),nginx不對(duì)該后端進(jìn)行連接,直到超過(guò)失效時(shí)間或者所有節(jié)點(diǎn)都失效后,該節(jié)點(diǎn)重新置為有效,重新探測(cè)。
b. 在fail_timeout時(shí)間內(nèi),被判定為down的后端server是不可能得到接收數(shù)據(jù)機(jī)會(huì)的,即使它恢復(fù)過(guò)來(lái)了!
c. fail_timeout時(shí)間過(guò)后,nginx會(huì)嘗試去通過(guò)發(fā)送數(shù)據(jù)請(qǐng)求到這個(gè)down的后端服務(wù)器上去測(cè)試它是否起來(lái)沒(méi)有。
?
1.3. 所有節(jié)點(diǎn)失效后nginx將重新恢復(fù)所有節(jié)點(diǎn)進(jìn)行探測(cè)
如果探測(cè)所有節(jié)點(diǎn)均失效,備機(jī)也為失效時(shí),那么nginx會(huì)對(duì)所有節(jié)點(diǎn)恢復(fù)為有效,重新嘗試探測(cè)有效節(jié)點(diǎn),如果探測(cè)到有效節(jié)點(diǎn)則返回正確節(jié)點(diǎn)內(nèi)容,如果還是全部錯(cuò)誤,那么繼續(xù)探測(cè)下去,當(dāng)沒(méi)有正確信息時(shí),節(jié)點(diǎn)失效時(shí)默認(rèn)返回狀態(tài)為502,但是下次訪問(wèn)節(jié)點(diǎn)時(shí)會(huì)繼續(xù)探測(cè)正確節(jié)點(diǎn),直到找到正確的為止。
?
2. proxy_next_upstream + proxy_connect_timeout
proxy_next_upstream
和proxy_connect_timeout
一起使用,就構(gòu)成了NGINX的故障轉(zhuǎn)移機(jī)制,使得在某一臺(tái)服務(wù)器無(wú)法連接或出現(xiàn)問(wèn)題(連接錯(cuò)誤、超時(shí)或者上游服務(wù)器返回特定 HTTP 狀態(tài)碼)時(shí),能夠嘗試將請(qǐng)求發(fā)送到下一臺(tái)服務(wù)器。
location / {
proxy_pass http://backend_servers;
proxy_connect_timeout 10s;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
# 其他配置項(xiàng)...
}
在此配置中,Nginx會(huì)首先嘗試連接到
backend1.example.com
。如果在5秒內(nèi)無(wú)法建立連接,或者該服務(wù)器返回500、502、503或504的HTTP狀態(tài)碼,Nginx將嘗試連接到下一個(gè)上游服務(wù)器backend2.example.com
。
?
3. Backup Servers
使用 backup 參數(shù)為某些上游服務(wù)器標(biāo)記為備份服務(wù)器。備份服務(wù)器僅在其他所有服務(wù)器不可用時(shí)才被使用。
示例:
upstream backend_servers {
server backend_server1;
server backend_server2 backup;
server backend_server3 backup;
}
這些方法可以單獨(dú)或組合使用,具體取決于需求和架構(gòu)。
?
六. 案例分析
1. 問(wèn)題描述
有一個(gè)發(fā)送短信的http服務(wù),客戶端調(diào)用之后,只有一次請(qǐng)求,但是發(fā)了三次短信。
2. 問(wèn)題分析與解決
分析:
- 代碼中沒(méi)有重試機(jī)制,通過(guò)請(qǐng)求分布來(lái)看,不是一臺(tái)機(jī)器處理了三次,而是每臺(tái)機(jī)器都處理了一次。
- 由nginx轉(zhuǎn)發(fā)導(dǎo)致。 查看接口的響應(yīng)時(shí)間發(fā)現(xiàn)每個(gè)接口的響應(yīng)時(shí)間為18s左右。分析是由于后端服務(wù)器未能及時(shí)返回?cái)?shù)據(jù),導(dǎo)致了nginx的超時(shí)重試機(jī)器,將請(qǐng)求分發(fā)到了另外一臺(tái)機(jī)器上。
查看nginx的配置文件,發(fā)現(xiàn)如下配置:
proxy_next_upstream http_502 http_504 error timeout invalid_header;
即實(shí)現(xiàn)了請(qǐng)求的故障轉(zhuǎn)移,此時(shí)說(shuō)明我們timeout設(shè)置的時(shí)間與實(shí)際接口請(qǐng)求情況不符。
?
解決方式:
nginx的熔斷機(jī)制
當(dāng)某臺(tái)服務(wù)器被(反向代理服務(wù)器)轉(zhuǎn)發(fā)處理請(qǐng)求,當(dāng)出現(xiàn)一定次數(shù)的錯(cuò)誤的情況下,nginx在一定時(shí)間內(nèi)不再將請(qǐng)求分配給這臺(tái)服務(wù)器進(jìn)行處理。 過(guò)了熔斷時(shí)間后,nginx會(huì)再次嘗試分配一次請(qǐng)求給該服務(wù)器處理,如果還是失敗,那么繼續(xù)熔斷。
upstream指令塊中server定義的熔斷參數(shù)配置
- max_fails = number; # 熔斷機(jī)制的錯(cuò)誤次數(shù) 閾值(默認(rèn)1)
- fail_timeout = time #熔斷時(shí)間(nginx標(biāo)記服務(wù)器不可用的持續(xù)時(shí)間,默認(rèn)10s)
配置如下:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-821126.html
...
upstream starrocks-tcp2
{
ip_hash;
server hostname1:8030 weight=1 max_fails=1 fail_timeout=10s; #Leader
server hostname2:8030 weight=1 max_fails=1 fail_timeout=10s; #Follower
server hostname3:8030 weight=1 max_fails=1 fail_timeout=10s; #Follower
}
...
?
參考:
《Nginx高性能Web服務(wù)器詳解》
https://zhuanlan.zhihu.com/p/547130562
nginx官網(wǎng) - ngx_stream_proxy_module文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-821126.html
到了這里,關(guān)于【nginx實(shí)戰(zhàn)】nginx正向代理、反向代理、由反向代理實(shí)現(xiàn)的負(fù)載均衡、故障轉(zhuǎn)移詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!