nginx-反向代理&負(fù)載均衡

什么是反向代理

有反向代理,那也就有正向的了,正向就是:客戶端=>服務(wù)端;

反向代理指的是代理服務(wù)器接受http請(qǐng)求,然后再將請(qǐng)求轉(zhuǎn)發(fā)給其他指定服務(wù)器,即分發(fā)請(qǐng)求;如下:

image.png

網(wǎng)上說反向代理能提升網(wǎng)站性能,但其實(shí)不是的,反而可能還會(huì)降低,因?yàn)橹虚g多了一層轉(zhuǎn)發(fā);說能提升網(wǎng)站性能的前提是搭配負(fù)載均衡;多個(gè)后端服務(wù)集群統(tǒng)一由反向代理服務(wù)器進(jìn)行請(qǐng)求分發(fā),這樣就避免了單臺(tái)服務(wù)器的性能瓶頸影響整個(gè)平臺(tái)的穩(wěn)定。

配置反向代理

最簡單的配置

這也是我們經(jīng)常做的前端反向代理配置

 location /api {
    proxy_pass http://www.51fubei.com/;
}

完整的配置

這是完整的反向代理配置,

location /api {
    add_header Cache-Control no-cache; // 設(shè)置response header
  add_header Content-Encoding gzip; // 設(shè)置response header
  proxy_set_header   Host local.baidu.com; // HTTP header 中的 Host 含義為所請(qǐng)求的目的主機(jī)名。當(dāng) nginx 作為反向代理使用,而后端真實(shí) web 服務(wù)器設(shè)置有類似 防盜鏈功能 ,或者根據(jù) HTTP header 中的 Host 字段來進(jìn)行 路由 或 過濾 功能的話,若作為反向代理的 nginx 不重寫請(qǐng)求頭中的 Host 字段,將會(huì)導(dǎo)致請(qǐng)求失敗。
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for; // HTTP header 中的 X_Forward_For 表示該條 http 請(qǐng)求是由誰發(fā)起的。如果反向代理服務(wù)器不重寫該請(qǐng)求頭的話,那么后端真實(shí) web 服務(wù)器在處理時(shí)會(huì)認(rèn)為所有的請(qǐng)求都來自反向代理服務(wù)器。如果后端 web 服務(wù)器有防攻擊策略的話,那么反向代理服務(wù)器對(duì)應(yīng)的 ip 地址就會(huì)被封掉。
  proxy_set_header   X-Real-IP        $remote_addr; // 真是IP
  proxy_pass         http://www.51fubei.com/;
  
  default_type  application/octet-stream; #默認(rèn)文件類型,默認(rèn)為text/plain
  #access_log off; #取消服務(wù)日志    
  log_format myFormat ' $remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定義格式
  access_log log/access.log myFormat;  #combined為日志格式的默認(rèn)值
  sendfile on;   #允許sendfile方式傳輸文件,默認(rèn)為off,可以在http塊,server塊,location塊。
  sendfile_max_chunk 100k;  #每個(gè)進(jìn)程每次調(diào)用傳輸數(shù)量不能大于設(shè)定的值,默認(rèn)為0,即不設(shè)上限。
  keepalive_timeout 65;  #連接超時(shí)時(shí)間,默認(rèn)為75s,可以在http,server,location塊。
  proxy_connect_timeout 1;   #nginx服務(wù)器與被代理的服務(wù)器建立連接的超時(shí)時(shí)間,默認(rèn)60秒
  proxy_read_timeout 1; #nginx服務(wù)器想被代理服務(wù)器組發(fā)出read請(qǐng)求后,等待響應(yīng)的超時(shí)間,默認(rèn)為60秒。
  proxy_send_timeout 1; #nginx服務(wù)器想被代理服務(wù)器組發(fā)出write請(qǐng)求后,等待響應(yīng)的超時(shí)間,默認(rèn)為60秒。
  proxy_http_version 1.0 ; #Nginx服務(wù)器提供代理服務(wù)的http協(xié)議版本1.0,1.1,默認(rèn)設(shè)置為1.0版本。
  #proxy_method get;    #支持客戶端的請(qǐng)求方法。post/get;
  proxy_ignore_client_abort on;  #客戶端斷網(wǎng)時(shí),nginx服務(wù)器是否終端對(duì)被代理服務(wù)器的請(qǐng)求。默認(rèn)為off。
  proxy_ignore_headers "Expires" "Set-Cookie";  #Nginx服務(wù)器不處理設(shè)置的http相應(yīng)投中的頭域,這里空格隔開可以設(shè)置多個(gè)。
  proxy_intercept_errors on;    #如果被代理服務(wù)器返回的狀態(tài)碼為400或者大于400,設(shè)置的error_page配置起作用。默認(rèn)為off。
  proxy_headers_hash_max_size 1024; #存放http報(bào)文頭的哈希表容量上限,默認(rèn)為512個(gè)字符。
  proxy_headers_hash_bucket_size 128; #nginx服務(wù)器申請(qǐng)存放http報(bào)文頭的哈希表容量大小。默認(rèn)為64個(gè)字符。
  proxy_next_upstream timeout;  #反向代理upstream中設(shè)置的服務(wù)器組,出現(xiàn)故障時(shí),被代理服務(wù)器返回的狀態(tài)值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off
  #proxy_ssl_session_reuse on; 默認(rèn)為on,如果我們在錯(cuò)誤日志中發(fā)現(xiàn)“SSL3_GET_FINSHED:digest check failed”的情況時(shí),可以將該指令設(shè)置為off。
}

設(shè)置了add_header后,可以直接訪問代理服務(wù)的時(shí)候,在response頭中看到,這邊添加了一個(gè)Cache-Control no-cache,如下:

image.png

設(shè)置了proxy_set_header后,在服務(wù)端請(qǐng)求中可以看到代理請(qǐng)求的header內(nèi)容,這邊自己起了一個(gè)node服務(wù),然后把request的內(nèi)容打印輸出了,這邊配置了Host、X-Forwarded-For、X-Real-IP,最終服務(wù)端接收到的header頭信息如下:

image.png

負(fù)載均衡

什么是負(fù)載均衡?其實(shí)比較容易理解,可以理解成餐廳門口有一個(gè)接待員,然后來1位顧客A,接待員就把顧客A分配給了服務(wù)員A,再來一位顧客B,接待員就分配給服務(wù)員B;如果一下來來了10位,則招待員就分別分配給服務(wù)員A、B、C、D、E,平均每個(gè)服務(wù)員接待兩個(gè),平均大家的工作量,而不會(huì)一個(gè)很忙,一個(gè)很閑;如果有一個(gè)服務(wù)員上廁所,那原本她的那個(gè)顧客會(huì)轉(zhuǎn)給其他幾個(gè)服務(wù)員接待;

專業(yè)的表述是:按照一定算法【權(quán)重、輪訓(xùn) 】,將客戶端請(qǐng)求轉(zhuǎn)發(fā)到不同應(yīng)用服務(wù)器上,減輕單個(gè)服務(wù)器壓力,提高系統(tǒng)并發(fā)量;并且能移除故障,通過心跳檢測方式,判斷應(yīng)用服務(wù)器是否正常工作,如果某一臺(tái)服務(wù)器宕機(jī)了,則會(huì)自動(dòng)將請(qǐng)求發(fā)送到其他應(yīng)用服務(wù)器去;如果檢測到服務(wù)器恢復(fù)了,則再添加到集群中來處理請(qǐng)求;如下圖所示:

image.png

熱備

如果主要服務(wù)器掛了,則會(huì)被備份服務(wù)器

upstream nodeserver {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002 backup; #如果127.0.0.1:8001掛了,則會(huì)走127.0.0.1:8002
}
    
server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
        location /api {
            add_header Cache-Control no-cache;
            proxy_pass http://nodeserver/;
            proxy_set_header Host local.baidu.com;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_connect_timeout 30s;
        }
}

輪訓(xùn)算法

輪訓(xùn)算法每一臺(tái)服務(wù)器的權(quán)重都是1,表示平均分配,所有請(qǐng)求按照順序分配,如上圖就是輪訓(xùn)平均分配請(qǐng)求;

upstream nodeserver {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
}

image.png

加權(quán)輪訓(xùn)算法

這邊可以設(shè)置權(quán)重大小,比如服務(wù)器A性能好一些,權(quán)重給3;服務(wù)器B性能差一些,權(quán)重給2;服務(wù)器C配置最差,權(quán)重給1;這個(gè)時(shí)候分配請(qǐng)求的量就會(huì)按照權(quán)重來按比例分配,50%的請(qǐng)求給到了A;33%的請(qǐng)求給到了B;17%的請(qǐng)求給到了C; 如下圖:

image.png

這邊以兩臺(tái)服務(wù)器來做測試,8002的權(quán)重是2;8001的權(quán)重是1,結(jié)果如下:

upstream nodeserver {
    server 127.0.0.1:8001 weight=1;
    server 127.0.0.1:8002 weight=2;
}
image.png

ip_hash

每個(gè)請(qǐng)求按訪問ip的hash結(jié)果分配,這樣每個(gè)訪客固定訪問一個(gè)應(yīng)用服務(wù)器,可以解決session共享的問題。

image.png

這邊以兩臺(tái)服務(wù)器來做測試,結(jié)果如下:

upstream nodeserver {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
  ip_hash;
}

最終請(qǐng)求只走到了8001這臺(tái)服務(wù)器,因?yàn)槲艺?qǐng)求ip沒有變;

image.png

當(dāng)我8001端口服務(wù)器掛了之后,請(qǐng)求就會(huì)被分配到8002端口服務(wù)器;

image.png

其他配置

upstream nodeserver {
    server 127.0.0.1:8001 down; #表示當(dāng)前的server暫時(shí)不參與負(fù)載
    server 127.0.0.1:8002 Weight=3; #默認(rèn)是1,表示平均分配;weight越大,負(fù)載的權(quán)重就越大
  server 127.0.0.1:8003 max_fails=1 fail_timeout=10s; #允許請(qǐng)求失敗的次數(shù);默認(rèn)是1,當(dāng)超過最大次數(shù)時(shí),返回proxy_next_upstream模塊定義的錯(cuò)誤,判斷該節(jié)點(diǎn)不可用,判斷不可用后10秒內(nèi)請(qǐng)求不會(huì) 轉(zhuǎn)發(fā)到此節(jié)點(diǎn),直到10秒后重新檢測節(jié)點(diǎn)健康情況;
  server 127.0.0.1:8003 backup; #其他服務(wù)器掛了之后,再請(qǐng)求backup服務(wù)器,所以這臺(tái)服務(wù)器是兜底的,壓力也是最輕的;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容