1、概述
代理(proxy),即中間人,它代替客戶端發送請求給服務器,收到響應後再轉給客戶端。一般意義上的代理是從用戶的角度講的,用戶經過某個代理能夠訪問多個網站,這個代理是靠近用戶的,好比某些公司可能須要限制員工所訪問的網站,就會在網絡出口處放置一個代理來作過濾。html
反向代理(reverse proxy),本質上跟代理是一回事,只不過是從服務器的角度講的,是靠近服務器的。好比某個網站有多個服務器,提供一樣的功能,通常會在網絡入口處放一個代理,接收客戶端的請求,再基於某種策略(好比輪轉)轉發給後端服務器,這樣能夠提升整個系統的服務能力。nginx 就是一種常見的 HTTP 協議反向代理。nginx
1.一、反向代理指令
nginx 中常見的反向代理指令有兩個:proxy_pass
和 fastcgi_pass
,前者使用標準的 HTTP 協議轉發,後者使用 FastCGI 協議轉發,用於 PHP 等架構的環境。在我要說的這個域名問題上,它們行爲是同樣的,因此下面僅以 proxy_pass
爲例。git
一個最簡單的反向代理配置以下:github
server { location / { proxy_pass https://github.com; } }
1.二、域名解析
其做用是將全部請求轉發到 github.com。注意此處寫的是域名,而非 IP。咱們知道在真正發起請求前,是須要將域名解析成 IP 的,對於 github.com 來講,在個人環境上它會被解析成兩個 IP:192.30.253.112 和 192.30.253.113,TTL 都是 50s,以下圖:後端
那麼使用上面這個配置,nginx 是何時作這件事情的呢?答案是啓動的時候,只作一次,解析結果會被緩存下來,也就是徹底無視 TTL,後續全部的請求轉發,都是直接使用緩存下來的 IP,不會再作任何域名解析。對於 github.com 這種返回多個 IP 的狀況,nginx 在轉發時會自動對 IP 列表進行輪轉。緩存
能夠使用 sudo tcpdump -n -i any port 53
抓包來驗證這個行爲。注:53 是 DNS 服務的默認端口。服務器
那麼問題來了,IP 變了怎麼辦?有什麼辦法讓 nginx 自動從新解析域名嗎?網絡
1.三、配置動態域名解析
resolver 8.8.8.8; server { location / { set $servers github.com; proxy_pass http://$servers; } }
如上,經過使用變量($servers
)的方式能夠強制 nginx 遵照域名解析結果的 TTL,過時後自動從新解析。不過這種寫法有個反作用,如此配置後 nginx 不會自動使用系統 /etc/resolve.conf
的配置,此時必須使用 resolver
指令手動給它指定一個 DNS 服務器。架構
其中 8.8.8.8是谷歌的開源免費DNS,國內的有114.114.114.114.若是是內網域名,須要制定內網的DNS服務器。tcp
參看地址:
https://github.com/inetfuture/blog/issues/4
https://www.nginx.com/blog/dns-service-discovery-nginx-plus/
2、反向代理
注意設置proxy_pass 後,同時須要設置proxy_set_header
proxy_set_header Host js.test.com; proxy_pass http://js.test.com/;
2.一、nginx location proxy_pass 後面的url 加與不加/的區別
在nginx中配置proxy_pass時,當在後面的url加上了/,至關因而絕對根路徑,則nginx不會把location中匹配的路徑部分代理走;若是沒有/,則會把匹配的路徑部分也給代理走。
在nginx中配置proxy_pass時,若是是按照^~匹配路徑時,要注意proxy_pass後的url最後的/,當加上了/,至關因而絕對根路徑,則nginx不會把location中匹配的路徑部分代理走;若是沒有/,則會把匹配的路徑部分也給代理走。
首先是location進行的是模糊匹配
1)沒有「/」時,location /abc/def能夠匹配/abc/defghi請求,也能夠匹配/abc/def/ghi等
2)而有「/」時,location /abc/def/不能匹配/abc/defghi請求,只能匹配/abc/def/anything這樣的請求
下面2種狀況分別用http://192.168.1.1/proxy/test.html 進行訪問。
一、proxy_pass後有 / 絕對路徑 不帶走 location 路徑
location /proxy/ { proxy_pass http://127.0.0.1:81/; }
結論:會被代理到http://127.0.0.1:81/test.html 這個url
擴展一、
location /proxy/ { proxy_pass http://127.0.0.1:81/ftlynx/; }
結論:會被代理到http://127.0.0.1:81/ftlynx/test.html 這個url。
擴展二、
location /proxy/ { proxy_pass http://127.0.0.1:81/ftlynx; }
結論:會被代理到http://127.0.0.1:81/ftlynxtest.html 這個url
二、proxy_pass 後沒有 / ,帶走location路徑
location /proxy/ { proxy_pass http://127.0.0.1:81; }
結論:會被代理到http://127.0.0.1:81/proxy/test.html 這個url
三、能夠經過的rewrite來實現/的功能