假設今天某公司提供了三個web服務,分別是服務1、服務2、服務3,這間公司希望把這三個服務架在同一台伺服器上,但網頁的port只有80(或https的443)能對外啊,有沒有辦法先讓請求統一發至port 80或443後再轉發給對應服務的port呢?有的,這就是反向代理(reverse proxy)的概念。
(反向代理示意圖)
我們先在伺服器架一個反向代理的服務在port 80上(本篇以Apache為例),然後設定轉發規則將往後收到的請求根據這個規則轉發至對應的服務。對應的服務處理完後再丟還給反向代理,反向代理再將結果回傳給使用者,完成一次循環。
Apache設定說明
概念在上面講完了,現在來講講怎麼設定Apache吧。首先啟用Apache的proxy
跟proxy_http
模組。
sudo a2enmod proxy
sudo a2enmod proxy_http
改/etc/apache2/sites-enabled/
裡面的.conf
加入以下幾行:
<VirtualHost *:80>
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
ProxyPass http://localhost:3000/
ProxyPassReverse http://localhost:3000/
</Location>
</VirtualHost>
- 將
ProxyPreserveHost
設定為On
的用意是在當請求被Apache的反向代理轉發給內部對應的服務時,不要去更動原本瀏覽器寫在請求表頭的Host
欄位,Apache請原封不動的轉發。 -
ProxyPass
這項後面接要轉發的目的地。假設我有個Node.js寫的web app掛在同一台機器的port 3000上,那我後面就填http://localhost:3000/
。 -
至於
ProxyPassReverse
又是什麼呢?假設今天我的服務產生了一個302 Redirect
的回傳:
HTTP/1.1 302 Found
Location: http://localhost:3000/new/place/
反向代理收到這個回傳後不應該原封不動把這個服務產生的回傳直接送回給使用者嘛,因為主機位址是內部使用的localhost:3000
對使用者來說是無意義的。
這時如果有設定ProxyPassReverse
的話,反向代理就會幫我們把localhost:3000
替換成原本使用者發來反向代理時的主機位址。這就是ProxyPassReverse
的功能。