Nginx反向代理與負載均衡
- 2019 年 10 月 12 日
- 筆記
最近在做需求的時候,有時候會和別的三方系統交互,如調用一個第三方系統的http介面查詢商品物流資訊,獲得響應數據返回給我們自己系統的前端頁面進行展示,整個流程會遇到什麼樣的問題呢,現在整理一下。
代理
大家都知道,我們平時開發,都是在公司的內網(區域網)中,即不能與外網(互聯網)交互,也就是不能上網,所以要想使開發機或伺服器能夠訪問外網,就不得不通過代理伺服器轉發請求了。這裡自然而然的就想到了使用Nginx做代理了,那什麼是代理呢?我們就先了解一下代理的基本概念吧。
代理一詞被我們在生活中所熟知,印象中的「代理」指的是以他人的名義,在授權範圍內進行對被代理人直接發生法律效力的法律行為。這是百度百科解釋的代理一詞的意思。通俗點說就是「代別人處理」,舉個生活中常見的例子,你去辦車檢,需要排隊辦理,也有很多表格要填,還要等待很久,辦下來差不多要一天。有些人嫌麻煩,浪費時間,不願意干,這個時候「代理車檢」這一職業就誕生了。你授權代理人幫你處理一些列繁瑣的事情,並支付一定的費用,你只需要關心結果,有沒有辦成功,其他的你不需要關心。這樣,你就從這一事務中脫離出來,交給專業的人去做。代理人執行的這一動作就叫做代理。
同樣,回到互聯網行業,代理一詞同樣適用。只不過這裡的代理人和被代理人都是電腦,即電腦1要訪問A站點,但是電腦1到A站點的網路不通,而電腦2到站點A的網路暢通,且電腦1和2之間能相互訪問,這時候電腦1想要訪問站點A,就可以通過電腦2轉發請求,電腦2再把響應轉發給電腦1,這時我們就說電腦1通過代理伺服器(或說使用了代理)完成了站點A的訪問,電腦2充當了代理伺服器的角色(代理人),電腦1充當客戶端的角色(被代理人)。
在這個圖中,電腦1/2/3組成一個區域網,但只有電腦2能訪問外網。假設企業的應用服務部署在電腦1和3甚至更多電腦上組成集群,如果某個功能需要調用站點A的http介面獲得數據,那麼部署在電腦1和3上的程式若直接請求站點A是不可行的,因為網路不通。但此時電腦2滿足訪問外網的條件,所以可以通過電腦2轉發電腦1和3發出的http請求,此時電腦2充當代理伺服器,作為系統內部與外界交互的中間人。代理,對外屏蔽了實際發起請求的電腦的IP。
反向代理
剛才介紹了代理,那麼什麼是反向代理呢?當然,它和正向代理相對 ,剛剛介紹的代理其實就是正向代理,至少在沒有反向代理之前它就叫做代理。反向代理是怎麼誕生的呢?這和互聯網和項目架構的發展有關,以前用戶量少業務少,項目往往部署在單台機器上,電腦2訪問站點A時明確知道站點A的IP和埠。因為只有一台伺服器,IP和埠是不變的,但隨著互聯網和系統業務的發展,以及用戶量的增長,業務的膨脹,傳統的單一架構已經支撐不了用戶需求,這個時候往往會選擇集群的方式增加系統的吞吐量,此時的站點A不再是部署在一台機器上,而是多個。伺服器1、2、3…組成一個應用集群對外提供服務,那現在電腦2怎麼訪問站點A呢?是訪問伺服器1、2、3中的哪一台呢?怎麼選擇訪問那一台伺服器呢?為了解決這個問題反向代理因運而生。
那為什麼叫反向代理呢?因為前面已經有了一個代理,所以為了區分另一種代理這種代理就叫做反向代理,往往把上面那種稱作正向代理。
如上圖,應用以集群模式部署在伺服器1、2、3上,外部客戶端訪問時通過伺服器4將請求轉發到具體的應用伺服器處理請求。對客戶端(電腦2)來說,只需知道伺服器4的IP和埠即可,具體由哪台應用伺服器處理請求是由伺服器4來決定的,此時伺服器4充當反向代理伺服器。反向代理,對外屏蔽了具體處理請求的伺服器的IP。伺服器4(反向代理)和電腦2(正向代理)就好比兩個國家的外交官,代表兩個國家對外發言。
Nginx
Nginx是特別受歡迎的一款產品,用來做反向代理和負載均衡,好處和優點我就不說了。
Nginx正向代理配置
如下,在nginx的配置文件nginx.conf中添加如下配置。
配置Nginx正向代理,監聽30000埠。
server { resolver 114.114.114.114;#指定dns伺服器 listen 30000;#監聽埠 access_log D:/mysoft/nginx/logs/proxy_access.log; error_log D:/mysoft/nginx/logs/proxy_error.log; location / { proxy_pass $scheme://$http_host$request_uri; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $host; proxy_set_header X-Forwarded-For $host; proxy_buffering on; proxy_buffer_size 32k; proxy_busy_buffers_size 256k; proxy_buffers 256 4k; proxy_max_temp_file_size 0; proxy_connect_timeout 30; proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; } }
Nginx反向代理+負載均衡配置
反向代理配置:
1、upstream模組配置服務集群ip+埠,默認負載均衡演算法是輪詢(即3台機器輪流處理請求);
2、server模組監聽80埠;
3、第一個 location 模組將請求後台介面的請求代理到upstream模組配置的服務集群;第二個location模組代理前端靜態資源,實現前後端分離。
#伺服器集群 upstream team_server { server 192.168.11.121:8080; server 192.168.11.122:8080; server 192.168.11.123:8080; } server { listen 80; server_name 192.168.11.128; charset utf-8; access_log D:/mysoft/nginx/logs/access.log main; error_log D:/mysoft/nginx/logs/error.log; location ~* /eroly/(.*)(/*.json|/*.do) { proxy_pass $scheme://team_server;#upstream的name proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location /eroly { root D:/static; rewrite ^/eroly/(.*?)$ /$1 break; } }
當訪問http://192.168.11.128/eroly/home/index.html,nginx會匹配到第二個location,若訪問的URL中以.json或.do結尾如/eroly/login.do時,Nginx會匹配到第一個location模組,將該請求轉發給upstream模組的一台伺服器進行處理 。
具體轉發給哪一台處理,由負載均衡演算法決定。
此時伺服器充當反向代理伺服器。
小結
正向代理: 一般在系統內部,只有正向代理伺服器能夠與外界交互,為了使應用伺服器在內網內能夠訪問外部介面,所以就需要通過正向代理伺服器做一層統一轉發。作用和優點:對內網內其他不能訪問外網的伺服器提供轉發服務,使其能通過代理髮送網路請求,對外屏蔽了實際發送網路請求的伺服器資訊。
反向代理: 不強調在系統內部只有反向代理伺服器能夠訪問外網(但一般也是部署在內網)。反向代理的側重點在於,在伺服器集群部署(往往需要負載均衡策略)的情況下,對外提供統一的IP和埠,便於外界訪問。(畢竟集群下多個伺服器對應多個IP)作用和優點:對外提供統一的入口(IP),便於客戶端訪問,保護實際處理請求的伺服器資訊。
正向代理和反向代理的區別
對等方不同: 正向代理服務的是內網內的其他電腦;反向代理服務的是客戶端,是對外服務的。
角色不同: 正向代理消費服務,向外發請求;反向代理提供服務對外處理請求。
問題延伸
同一台機器既充當正向代理伺服器又充當反向代理伺服器嗎?
答案是肯定的。
舉個例子,例如上圖,淘寶和物流系統是兩個不同的系統,屬於兩個公司,各自的服務獨立集群部署。淘寶為用戶提供網購服務,此時淘寶是服務端;當用戶點擊查看淘寶里的商品物流資訊時,淘寶的伺服器需要訪問第三方物流系統,對物流系統來說它為淘寶提供查詢物流服務,此時淘寶是客戶端,物流系統是服務端。
所以,淘寶的代理伺服器即是正向代理伺服器又是反向代理伺服器。反向代理面向用戶訪問淘寶伺服器,正向代理面向淘寶的內部伺服器訪問三方物流系統。物流系統的代理伺服器在這個例子中僅充當反向代理伺服器。
錯誤程式碼502、504、 400
1、502 Bad Gateway,偶現502
比如我剛剛打開部落格園的一篇文章時,等了一會出現這樣的畫面。
【502 錯誤的網關 代理伺服器收到來自上游伺服器的無效響應。】
502 Bad Gateway是指錯誤網關,無效網關;在互聯網中表示一種網路錯誤。表現在WEB瀏覽器中給出的頁面回饋。
含義:這通常並不意味著上游伺服器已關閉(無響應網關/代理) ,而是上游伺服器和網關/代理使用不一致的協議交換數據。鑒於互聯網協議是相當清楚的,它往往意味著一個或兩個機器已不正確或不完全編程。–百度百科
意思是報這個錯並不一定不是部落格園的伺服器已關閉,這個時候就要看一下多次訪問是不是都會報錯。
回到我們的問題上,我們訪問別人的介面時,偶爾報這個錯,可能是由於對方服務沒有正常返迴響應造成的,為什麼沒有正常返迴響應?原因可能是對方服務介面限流導致拒絕訪問,總之就是對方服務在某些情況下為了保護自身系統而沒有正常響應數據。如果是一直502而不是偶現,可以參考這篇https://www.cnblogs.com/ibigboy/p/11248343.html,如果還不行那就需要對方看了。
2、504 Gateway Time-out
一般是網不通,可Telnet,可ping,但還是報504,此時先考慮自己的正向代理服務是不是正常,主要看能不能訪問別的三方介面,看看是不是配置成了只能代理http或https的,代理配置是否正確,其次再考慮對方服務是不是沒有啟動,或對方把網關了(在實際開發中遇到過,國慶期間對方把網封了),需對方協助解決。
3、400 Bad Request
參數傳錯了,不符合對方要求,參數名和實體類不對應,或前端沒有傳json。具體看這篇https://www.cnblogs.com/ibigboy/p/11242776.html
原文首發於公眾號編程大道,歡迎關注