如何理解正向和反向代理
個人感覺這兩個概念技術是很相似的,都是接收客戶端的請求,并將這些請求轉發給另一臺服務器,然后將服務器的響應返回給客戶端。
但是他們的使用場景和目標又有很大不同的。
正向代理
正確叫法是:Forward Proxy,譯為:正向代理、前置代理、前向代理、客戶端代理
主要是面向客戶端的。最大的特點就是,在代理的過程中隱藏了真實的請求客戶端,服務端不知道真實的客戶端是誰。
比如我們耳熟能詳的VPN做的事情,就是這個。
也就是說,必須在客戶端上面做一些操作,讓你的流量全部通過代理服務器去訪問網絡,外部識別到的都是你的代理服務器的身份,無法追蹤到你的實際ip。
如上圖所示, 所有客戶端(Client A、B)全部都會被偽裝 C 來訪問訪問外部網絡。
很多公司為了內部網絡安全,都會做網關進行管理。
反向代理
正確叫法是:Reverse Proxy,譯為:反向代理、反向代理服務器、逆向代理、服務器代理
主要是面向服務端的,最大的特點就是,從客戶端角度來看,并不知道真實訪問的服務器是誰,只知道公開的服務器入口。
如上圖所示,客戶端都是去訪問 google.com 但是并不知道最終的服務器實際地址。
顯而易見的,這樣就很輕松的將客戶端請求分發到了多臺服務器,實現負載均衡,并且還能保護實際服務器,當然還有一些其他的好處。
下面用Nginx來列舉一些反向代理的使用場景:
1. 負載均衡
你可以使用Nginx將進入的請求分發到多臺后端服務器。這在配置文件中看起來可能像這樣:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen80;
location / {
proxy_pass http://backend;
}
}
}
在這個配置中,upstream 指令定義了一個包含多個服務器的服務器組。然后,在 location 塊中,proxy_pass 指令將客戶端的請求轉發到 backend 服務器組中的服務器。
這里默認采用的是輪詢的負載均衡方法。
Nginx會按照服務器的定義順序,依次將每個新的請求轉發到不同的后端服務器。如果所有的后端服務器對于請求的處理速度都大致相同,這種方法是有效的。
加權輪詢(Weighted Round Robin):
這是輪詢的擴展。你可以為每個后端服務器指定一個權重(weight),權重較高的服務器將接收更多的請求。
這在后端服務器性能不均勻時很有用。配置看起來可能像這樣:
http{
upstreambackend {
serverbackend1.example.com weight=3;
serverbackend2.example.com;
serverbackend3.example.com;
}
...
}
在這個例子中,backend1.example.com 由于權重設為3,將接收三倍于其他服務器的請求。
最少連接(Least Connections):
這種方法會將新的請求轉發到當前活躍連接數最少的服務器,適合處理請求處理時間長短不一的情況。
配置看起來可能像這樣:
http{
upstreambackend {
least_conn;
serverbackend1.example.com;
serverbackend2.example.com;
serverbackend3.example.com;
}
...
}
IP Hash:
這種方法根據客戶端的IP地址決定將請求發送到哪個服務器,可以用于實現會話持久性(session persistence)。
配置看起來可能像這樣:
http{
upstreambackend {
ip_hash;
serverbackend1.example.com;
serverbackend2.example.com;
serverbackend3.example.com;
}
...
}
在這個例子中,ip_hash 指令讓 Nginx 使用 IP Hash 的方法來分配請求。具體來說,Nginx 會根據客戶端的 IP 地址計算一個哈希值,然后根據這個哈希值將請求分發給某一個特定的后端服務器。因此,來自同一個客戶端 IP 的請求總是會被發送到同一臺后端服務器,這樣就可以實現會話保持。
還有其他一些規則,這里就不一一介紹了。
2. SSL終端
在Nginx中,你可以配置反向代理來處理所有的SSL/TLS握手過程。配置看起來可能像這樣:
server {
listen443 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
proxy_pass http://backend;
}
}
在這個配置中,listen 指令讓Nginx在443端口(默認的HTTPS端口)上監聽請求,ssl_certificate 和 ssl_certificate_key 指定了SSL證書和私鑰的位置。然后,所有的HTTPS請求都會被轉發到 backend 服務器組。
簡單的說,只需要在你的代理服務器上配置好SSL證書,進行https訪問,訪問實際服務器的時候,采用http(非加密的方式)。
這種將解密后的請求轉發到后端服務器,可以大大減輕后端服務器的計算壓力。
3. 緩存
Nginx也可以配置為緩存代理,將后端服務器的響應結果(如網頁、圖片、視頻等)暫存到本地磁盤或內存中,提高對相同請求的處理速度。
當收到相同的請求時,直接從緩存中提供服務,而無需再次訪問后端服務器,這可以大大提高服務的響應速度和后端服務器的處理能力。另外,反向代理還可以對響應內容進行優化,如壓縮、添加緩存控制頭等。
某種意義上來說我們使用的CDN服務器,采用的就是類似的做法。
配置看起來可能像這樣:
http {
proxy_cache_path /data/nginx/cache levels=1:2 keys_znotallow=my_cache:10m;
server {
listen80;
location / {
proxy_cache my_cache;
proxy_pass http://backend;
}
}
}
在這個配置中,proxy_cache_path 指令定義了緩存的存儲路徑和其他參數,proxy_cache 指令使得在 / 位置的請求啟用緩存。
4. 安全
反向代理還可以提供額外的安全層,它可以隱藏后端服務器的信息,防止惡意攻擊直接達到后端服務器。
同時,它還可以實施各種安全策略,如阻止來自特定IP地址的請求,限制并發連接數等。
反向代理舉例
Chatapi反代
server {
listen443 ssl;
server_name chatapi.xxxxx.com;
ssl_certificate /etc/nginx/cert/chatapi.xxxxx.com.crt;
ssl_certificate_key /etc/nginx/cert/chatapi.xxxxx.com.key;
location / {
proxy_pass https://api.openai.com/;
proxy_ssl_server_nameon;
proxy_set_header Host api.openai.com;
proxy_set_header Connection '';
proxy_http_version1.1;
chunked_transfer_encodingoff;
proxy_bufferingoff;
proxy_cacheoff;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
access_log /www/access_nginx.log combined;
}
這樣的話就可以用 chatapi.xxxxx.com 去替代 api.openai.com 了,解決了在國內直接訪問的問題
還有很多其他的應用場景,這里就不一一列舉了。