反向代理是nginx的主要功能之一清钥,平時我們在使用Nginx的時候一般就是用其性能高效的反向代理功能艺谆。
為了線上環(huán)境中的降級和服務(wù)替換颗搂,nginx的upstream模塊提供了通用的參數(shù)靶草。
通用的參數(shù)有(不論是round-robin蹄胰,還是hash)
- backup:指定當(dāng)前server為備份服務(wù),當(dāng)且僅當(dāng)所有的非備份服務(wù)器不可用的時候奕翔,請求才會轉(zhuǎn)發(fā)到該server裕寨。
- down:標(biāo)識某臺服務(wù)已經(jīng)下線,不在服務(wù)派继。
round-robin算法
round-robin 輪詢是nginx反向代理的默認使用的算法宾袜。
指定上游服務(wù)地址的upstream模塊。
指令驾窟。
upstream backend1{
server 192.168.0.2:80 weight=1 max_fails=3 fail_timeout=30s;
}
- weight: 服務(wù)器的訪問權(quán)重
- max_conns: server的最大并發(fā)連接數(shù)字庆猫,僅作用于單worker進程。默認是0绅络,表示沒有限制月培。
- max_fails: 在fail_timeout 時間段內(nèi)嘁字,最大的失敗次數(shù),當(dāng)達到最大的失敗次數(shù)時杉畜,會在fail_timeout 秒內(nèi)這臺server 不會再次選中纪蜒。
- fail_timeout:單位為秒,默認是10s此叠。具有兩個功能(配合max_fails 使用)如上所述纯续。
對上游服務(wù)使用keepalive長連接
通過復(fù)用tcp連接,降低nginx與上游服務(wù)器的建立灭袁、關(guān)閉連接的消耗猬错,提高吞吐量的同時降低時延。
對上游連接設(shè)定的http頭部(因為http1.0 不支持keepalive)
proxy_http_version 1.1;
proxy_set_header Connection "";
- keepalive connections:向一組upstream最多保持多少個空閑的tcp連接用來keepalive請求茸歧。Nginx 和后端的長連接不夠用時 Nginx 會新建連接來處理新的請求(是 Nginx 每個 worker 連接后端的最大長連接數(shù)倦炒,而不是整個 Nginx 的)
- keepalive_requests number:1.15.3新增指令。一條keepalive上最多跑多少條請求举娩。
- keepalive_timeout:1.15.3新增指令析校。一條tcp連接,超過多長時間沒有請求的話铜涉,關(guān)閉tcp智玻。
- resolver:當(dāng)使用域名訪問時,指定我們自己的dns服務(wù)器芙代。
- resolver_timeout:dns超時時間吊奢。
測試
如下是我nginx的配置。
upstream backend {
keepalive 32;
server 192.168.199.214:8081 weight=1 max_fails=2 fail_timeout=5s;
server 192.168.199.214:8082 weight=1 max_fails=2 fail_timeout=5s;
}
server {
listen 80;
server_name app.prometheus.wjx;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://backend;
}
}
一臺后端掛了后纹烹,nginx如何處理
當(dāng)我將8081 的這臺機器掛掉后页滚。
從tcp層面會有RST,也就是http無法再用這條tcp連接铺呵。所以當(dāng)然http請求是無法發(fā)送到8081這臺機器裹驰,nginx會默認將請求發(fā)往下一臺server 8082。tcp建立通了片挂,才會有http請求過去幻林,也就是說nginx是有高效的錯誤處理能力的。當(dāng)配置的5s后(不一定就5s)音念,nginx會再試8081 端的server沪饺,5s后再有請求,會重新嘗試與8081建立tcp連接闷愤。
keepalive 對nginx和后端的影響
- 當(dāng)keepalive配置只有1,壓力測試
ab -n 10 -c 2 http://localhost/
從上圖可以看出整葡,其實只有一個keepalive連接,其他的還是使用了短連接讥脐。
-
當(dāng)keepalive為2048時遭居,壓力測試
只建立了兩個tcp連接啼器,分別是兩個后端server的。也就是每個server一條連接魏滚,傳輸了所有的數(shù)據(jù)镀首。
-
不開啟keepalive。壓力測試
開啟keepalive的時候鼠次,nginx的timewait達到了 14000+個。而server端的timewait幾乎為0芋齿。(因為開啟時腥寇,server會認為這是一個長連接,不會主動關(guān)閉觅捆,而不開啟的話赦役,server會在一次請求結(jié)束后主動關(guān)閉長連接)
不開啟keepalive的時候,nginx的timewait為1000+個栅炒,而server端為900+個掂摔。
而看看抓包情況。赢赊。乙漓。滿屏的tcp syn握手包。
least_conn 算法
這個算法是由upstream_least_conn 模塊提供的释移。功能是從所有的上游服務(wù)中找出并發(fā)連接數(shù)最少的一個叭披,將請求轉(zhuǎn)發(fā)到它。
一般很少用到玩讳,當(dāng)所有的server的連接都相同的時候涩蜘,該算法會退化成round_robin算法。
upstream模塊提供的變量
變量 | 作用 |
---|---|
upstream_addr | 上游服務(wù)的ip地址+port |
upstream_connect_time | 與上游服務(wù)建立連接消耗的時間 |
upstream_header_time | 接收上游服務(wù)發(fā)回響應(yīng)的頭部消耗的時間 |
upstream_response_time | 接收上游服務(wù)響應(yīng)消耗的時間 |
upstream_bytes_received | 從上游服務(wù)接收到的響應(yīng)長度 |
upstream_response_length | 從上游服務(wù)返回的響應(yīng)包體的長度 |
upstream_status | 上游服務(wù)的返回的狀態(tài)碼未連接上是502 |
proxy 模塊
proxy_pass 是反向代理中最重要的一個模塊熏纯。
其大體流程如圖所示同诫。
proxy_request_buffering 和 proxy_buffering 為 off 時才會邊讀包體邊發(fā)送
根據(jù)指令生成發(fā)往上游的請求行
- proxy_method method : 將請求方法
- proxy_http_version 1.0|1.1 : 更改http的version(keepalive就需要1.1)
- proxy_set_header :添加頭部
- proxy_pass_request_headers on|off :是否將用戶請求的包頭發(fā)給上游(默認當(dāng)然是發(fā)的)。
- proxy_pass_request_body on|off:是否將用戶請求包體發(fā)給上游(默認當(dāng)然是發(fā)的)樟澜。
- proxy_set_body value:添加包體
接收客戶端請求的包體
- proxy_request_buffering on|off 上面已經(jīng)說了off的話會邊收包體邊發(fā)误窖。
- on:1.客戶端網(wǎng)速慢。2.上游服務(wù)并發(fā)處理能力低往扔。3.適應(yīng)高吞吐場景贩猎。
- off:1.更及時的響應(yīng)。2.降低nginx讀寫磁盤的消耗萍膛。 3.一旦開始發(fā)送 proxy_next_upstream 功能失敗吭服。
- client_body_buffer_size size:接收請求的header時,為接收到包體分配內(nèi)存蝗罗。默認8k或16k艇棕。
- 若接收頭部時已經(jīng)接收完全部包體蝌戒,則不分配。
- 若剩余待接收包體長度小于client_body_buffer_size, 則分配所需大小
- client_max_body_size size :允許請求包體最大長度的限制沼琉,默認是1M
- client_body_temp_path path:臨時文件的路徑(放請求body的)
- client_body_in_file_only on | clean | off:默認是off 的北苟。一般是請求body寫到文件中,on的話是永久保存的打瘪,一般用于定位問題友鼻。
- client_body_timeout time:讀取包體時超時,則返回408錯誤闺骚。
nginx與上游服務(wù)建立連接
- proxy_connect_timeout time :與上游服務(wù)建立tcp連接的超時時間彩扔。超時后會生成502。(默認60s)
- proxy_socket_keepalive on|off:當(dāng)設(shè)置為on時僻爽,會使用操作系統(tǒng)的tcp去操作tcp keepalive虫碉。
- keepalive:有幾個keepalive。
- keepalive_requests:連接最多執(zhí)行多少個http請求胸梆。
- proxy_ignore_client_abort on|off:當(dāng)client關(guān)閉連接敦捧,是否關(guān)閉與upstream關(guān)閉(默認是off的,on的話對上游壓力很大)
- proxy_send_timeout:向upstream發(fā)送請求的超時時間碰镜。
nginx接收upstream的響應(yīng)
- proxy_buffer_size size:
- proxy_buffering on|off:off為邊發(fā)邊收兢卵。
- proxy_buffers number size:當(dāng)不是邊發(fā)邊收的情況下就需要將包體寫到磁盤中,但是磁盤還是比較慢的洋措。如果這里指定了buffer济蝉,小文件(buffer能存放下)就不會寫文件了。
- proxy_max_temp_file_size size:限制upstream回返的包體寫入磁盤的最大值菠发。默認是1G王滤。
- proxy_temp_file_write_size size:限制每一次向臨時磁盤文件寫入的字節(jié)數(shù)。
- proxy_temp_path path [level1 [level2 [level3]]]:臨時文件寫入的文件目錄滓鸠。
- proxy_busy_buffers_size size:及時轉(zhuǎn)發(fā)包體雁乡,先向客戶端轉(zhuǎn)發(fā)接收到的size字節(jié)。
- proxy_read_timeout time:讀取超時時間糜俗。
- proxy_limit_rate rate :限速讀取上游的響應(yīng)踱稍。
上游出現(xiàn)失敗時的容錯方案
當(dāng)upstream的上游服務(wù)返回失敗時的處理方法。
- proxy_next_upstream
當(dāng)出現(xiàn)錯誤悠抹,超時珠月,錯誤頭部,指定的返回碼楔敌。 - proxy_next_upstream_timeout 超時時間
- proxy_next_upstream-tries 重試次數(shù)
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 1s;
proxy_next_upstream off;
proxy_pass http://backend;
}
proxy_next_upsteam
- off :錯誤了還是返回啤挎。
- error:屏蔽錯誤,502。
- http_500:500 錯誤會被屏蔽