nginx的反向代理

反向代理是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和后端的影響
  1. 當(dāng)keepalive配置只有1,壓力測試
ab -n 10 -c 2 http://localhost/
wireshark抓包

從上圖可以看出整葡,其實只有一個keepalive連接,其他的還是使用了短連接讥脐。

  1. 當(dāng)keepalive為2048時遭居,壓力測試
    只建立了兩個tcp連接啼器,分別是兩個后端server的。也就是每個server一條連接魏滚,傳輸了所有的數(shù)據(jù)镀首。


    wireshark抓包
  2. 不開啟keepalive。壓力測試
    開啟keepalive的時候鼠次,nginx的timewait達到了 14000+個。而server端的timewait幾乎為0芋齿。(因為開啟時腥寇,server會認為這是一個長連接,不會主動關(guān)閉觅捆,而不開啟的話赦役,server會在一次請求結(jié)束后主動關(guān)閉長連接)
    不開啟keepalive的時候,nginx的timewait為1000+個栅炒,而server端為900+個掂摔。
    而看看抓包情況。赢赊。乙漓。滿屏的tcp syn握手包。


    wireshark握手包

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_pass.png

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 錯誤會被屏蔽
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卵凑,一起剝皮案震驚了整個濱河市庆聘,隨后出現(xiàn)的幾起案子胜臊,更是在濱河造成了極大的恐慌,老刑警劉巖伙判,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件象对,死亡現(xiàn)場離奇詭異,居然都是意外死亡宴抚,警方通過查閱死者的電腦和手機勒魔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菇曲,“玉大人沥邻,你說我怎么就攤上這事⊙蛲蓿” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵埃跷,是天一觀的道長蕊玷。 經(jīng)常有香客問我,道長弥雹,這世上最難降的妖魔是什么垃帅? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮剪勿,結(jié)果婚禮上贸诚,老公的妹妹穿的比我還像新娘。我一直安慰自己厕吉,他們只是感情好酱固,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著头朱,像睡著了一般运悲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上项钮,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天班眯,我揣著相機與錄音,去河邊找鬼烁巫。 笑死署隘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亚隙。 我是一名探鬼主播磁餐,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恃鞋!你這毒婦竟也來了崖媚?” 一聲冷哼從身側(cè)響起亦歉,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畅哑,沒想到半個月后肴楷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡荠呐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年赛蔫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泥张。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡呵恢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出媚创,到底是詐尸還是另有隱情渗钉,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布钞钙,位于F島的核電站鳄橘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芒炼。R本人自食惡果不足惜瘫怜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望本刽。 院中可真熱鬧鲸湃,春花似錦、人聲如沸子寓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽别瞭。三九已至窿祥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝙寨,已是汗流浹背晒衩。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留墙歪,地道東北人听系。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像虹菲,于是被迫代替她去往敵國和親靠胜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容