背景
在日常運維工作中,常常會用到反向代理,為了更安全同時為了負載均衡,分擔壓力。
那么,有小伙伴就會有疑問:
- 什么是反向代理?
- 負載均衡又是怎么實現的?
- 有反向代理那有正向代理嗎?
- 正向代理的應用場景是怎樣的?
- 反向代理和正向代理怎么配置實現呢?
帶著這些疑問,就給大家詳細解釋下Nginx的正反向代理。
環境
Nginx(Nginx是一款自由的、開源的、高性能的HTTP服務器。功能優勢等等這里就不再贅述了。度娘那里有很多信息。)
代理
說到代理,首先我們要明確一個概念,所謂代理就是一個代表、一個渠道;
此時就設計到兩個角色,一個是被代理角色,一個是目標角色,被代理角色通過這個代理訪問目標角色完成一些任務的過程稱為代理操作過程;如同生活中的專賣店~客人到adidas專賣店買了一雙鞋,這個專賣店就是代理,被代理角色就是adidas廠家,目標角色就是用戶。
反向代理
我們在運維的日常工作中經常用到負載均衡,所以接觸反向代理比較多,那么反向代理是怎樣的呢?。例如人氣比較高的網站,如淘寶,京東等等。每天訪問人數的人很多,數以萬計,此時單臺服務器遠遠不能承載所有人的訪問請求,這時作為資深運維人員就需要對web服務進行分布式部署;何為分布式部署呢?就是通過部署多臺服務器組成web集群共同來處理訪問請求,解決單臺服務器不能承載的問題;分布式部署的web服務可以橫行擴展。而實現web分布式部署通常要用到反向代理。Apache或nginx都可以。本文以nginx為例,用nginx的反向代理實現的。國內公司通過把nginx和其他的組件進行封裝,根據場景或側重點不同,便于構建安裝,就有了:Tengine或OpenResty等。有興趣的朋友可以度娘搜索學習。那么反向代理具體是通過什么樣的方式實現的分布式的集群操作呢,我們先看一個示意圖:

通過上述的圖解大家就可以看清楚了,多個客戶端給服務器發送的請求,nginx服務器接收到之后,按照一定的規則分發給了后端的web服務器進行處理了。此時請求的來源也就是客戶端是明確的,但是請求后具體由哪臺服務器進行處理響應并不明確了,web服務(nginx)扮演的就是一個反向代理角色。
反向代理,主要用于服務器集群分布式部署負載均衡共同承載請求壓力或安全需求等的情況下使用,反向代理可以隱藏了響應服務器的信息,能夠過濾網絡攻擊,保證安全。
正向代理
陰陽兩儀生萬物,有陰就有陽,有反就有正。說完反向代理了,我們再來看看正向代理。正向代理可能在日常工作中用的不是很多,但是,相信大家經常聽到:翻墻這個詞,何為翻墻呢?翻墻是因為大陸對網絡中攻擊等等進行了屏蔽和過濾,相當于防火墻的墻一樣,允許的我們才可以訪問,屏蔽的我們就不能訪問。這是我們做技術的如果需要在國外查詢技術文檔等就需要翻墻,通常我們需要購買vpn來實現,vpn的功能就是用的正向代理。那么vpn是怎么實現的呢?我們如果需要訪問國外的某些網站,此時你會發現位于國外的某網站我們通過瀏覽器是沒有辦法訪問的,被屏蔽過濾掉了。vpn的方式就是找一個可以正常訪問國外網站的代理服務器,我們將請求發送給代理服務器,然后代理服務器去訪問國外的網站,然后將訪問到的數據傳遞給我們!
上述描述的代理模式稱為正向代理,正向代理的特點是:客戶端非常明確要訪問的服務器地址;服務器只清楚請求來自哪個代理服務器,但是不清楚來自哪個具體的客戶端;正向代理模式屏蔽或者隱藏了真實客戶端信息。如下圖

正反向代理共同使用
日常在實際項目操作中,正向代理和反向代理會搭配使用。正向代理代理客戶端的請求去訪問目標服務器,而目標服務器是又使用反向代理服務器,反向代理多臺真實的業務處理服務器,進行負載均衡。具體的拓撲圖如下:

負載均衡
我們知道了代理服務器,也一直說負載均衡,何為負載均衡呢?簡單的說:web服務(nginx)作為反向代理服務器,依據一定的規則對請求進行分發,把請求平均讓后端業務服務器進行響應,已達到分擔壓力的作用。負載就是客戶端對業務發送的請求,分發到不同的服務器處理的規則,就是一種均衡規則。將服務器接收到的請求按照規則分發的過程,就是負載均衡。
負載均衡,有硬件負載均衡和軟件負載均衡兩種,硬件負載均衡也稱為硬負載,如F5負載均衡,但是相對造價昂貴成本較高,但是數據的穩定性安全性等等有非常好的保障,如國有企業三大運營商這樣的公司才會選擇硬負載進行操作;通常公司都會考慮到成本問題,會選擇使用軟件負載均衡,軟件負載均衡是利用現有的技術結合主機硬件實現的一種消息隊列分發機制。軟件負載均衡肯定和硬負載沒法比較的,但是成本較低,穩定性和安全性在架構優化后在可接受范圍,廣為使用。
nginx的負載均衡規則如下:
- weight輪詢(默認):接收到的請求按照順序逐一分配到不同的后端服務器,即使在使用過程中,某一臺后端服務器宕機,nginx會自動將該服務器剔除出隊列,請求受理情況不會受到任何影響。這種方式下,可以給不同的后端服務器設置一個權重值(weight),用于調整不同的服務器上請求的分配率;權重數據越大,被分配到請求的幾率越大;該權重值,主要是針對實際工作環境中不同的后端服務器硬件配置進行調整的。
- ip_hash:每個請求按照發起客戶端的ip的hash結果進行匹配,這樣的算法下一個固定ip地址的客戶端總會訪問到同一個后端服務器,這也在一定程度上解決了集群部署環境下session共享的問題。
- fair:智能調整調度算法,動態的根據后端服務器的請求處理到響應的時間進行均衡分配,響應時間短處理效率高的服務器分配到請求的概率高,響應時間長處理效率低的服務器分配到的請求少;結合了前兩者的優點的一種調度算法。但是需要注意的是nginx默認不支持fair算法,如果要使用這種調度算法,請安裝upstream_fair模塊
- url_hash:按照訪問的url的hash結果分配請求,每個請求的url會指向后端固定的某個服務器,可以在nginx作為靜態服務器的情況下提高緩存效率。同樣要注意nginx默認不支持這種調度算法,要使用的話需要安裝nginx的hash軟件包
具體實現
了解了正反向代理和負載均衡,那么要怎么實現呢?如何去配置。
正向代理配置
現在我登錄上代理服務器上, 打開/etc/nginx/conf.d/default.conf 添加 resolver和 proxy_pass,設置如下:
server { listen 80; server_name localhost nginx.tangll.cn; resolver 8.8.8.8; location / { proxy_pass http://$http_host$request_uri; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }}
resolver為DNS解析,這里填寫的IP為google提供的免費DNS服務器的IP地址。proxy_pass配置代理轉發。至此便是配置了代理服務器,所有訪問請求全部都通過代理服務器轉發, $http_host就是我們要訪問的主機名, $request_uri就是我們后面所加的參數。簡單的說至此就是相當于配置好了我們請求了代理服務器,代理服務器再去請求我們所請求的地址。
然后,只需要在本機系統或瀏覽器配置代理即可訪問。
windows配置

linux系統
使用yum 的設置代理的方法
如果只需要使用yum來更新包的,只需進行yum配置即可。
[root@localhost ~]# vim /etc/yum.conf proxy=http://192.168.99.99:80#proxy=ftp://192.168.99.99:80#proxy_username=username #####代理的用戶名#proxy_password=password #####代理的密碼#然后直接用yum安裝即可
wget設置代理的方法
[root@localhost ~]# vim /etc/wgetrchttp_proxy=192.168.99.99:80http_proxy=192.168.99.99:443
curl訪問代理設置的方法
#如果訪問HTTP網站,可以直接這樣的方式: curl --proxy proxy_server:80 http://www.taobao.com/#如果訪問HTTPS網站,例如https://www.alipay.com,那么可以使用nginx的HTTPS轉發的server:curl --proxy proxy_server:443 http://www.alipay.com[root@localhost ~]# curl -I --proxy 192.168.99.99:80 www.baidu.com ###顯示http訪問的狀態碼HTTP/1.1 200 OK備注:上邊有介紹,詳見上邊內容。
使用設置全局代理的方法
[root@localhost ~]# vim /etc/profilehttp_proxy = http://192.168.99.99:80http_proxy = http://192.168.99.99:443ftp_proxy = http://192.168.99.99:80/export http_proxyexport ftp_proxy
反向代理配置
反向代理的演示更為簡單一些。首先在/etc/nginx/conf.d/下新建一個default.conf:
server { listen 80; server_name localhost nginx.tangll.cn; location / { root /usr/share/nginx/html; index index.html index.htm; } #設置代理 location / { proxy_pass http://127.0.0.1:8080; } error_page 500 502 503 504 404 /50x.html; location = /50x.html { root /usr/share/nginx/html; }}
總結
代理服務器站在客戶端那邊就是正向代理,代理服務器站在原始服務器那邊就是反向代理, Nginx通過 proxy_pass可以設置代理服務。