利用Apache的轉發模組實現反向代理伺服器
問題又來
公司的LAMP伺服器使用Apache的VirtualHost功能部署了多個擁有獨立域名的網站。httpd.conf配置檔案部分如下:
# 省略本文無關部分
Listen 80
# www.xxx.com
<VirtualHost *>
ServerAdmin xxx@126.com
DocumentRoot "/var/www/xxx"
ServerName www.xxx.com
</VirtualHost>
# www.yyy.com
<VirtualHost *>
ServerAdmin yyy@126.com
DocumentRoot "/var/www/yyy"
ServerName yyy.com
ServerAlias www.yyy.com
</VirtualHost>
# 省略其他網站配置
可見,Apache偵聽在80埠上,並依據域名來分發請求到不同的網站目錄。
今天,公司決定在這個伺服器上增加一個網站,該網站擁有獨立域名zzz.com,使用JavaEE開發,基於Tomcat執行。
由於已經有Apache偵聽80埠,所以獨立執行的Tomcat必然無法再偵聽這個埠。而客戶要求必須以http://www.zzz.com的形式訪問網站,而不能是http://www.zzz.com:8080。所以必須把Tomcat整合到Apache下面。
解決思路
要把Tomcat網站整合到Apache中,主要方式有兩種。一是通過AJP協議,把Tomcat作為Apache的worker;二是使用mod_proxy和mod_proxy_http模組轉發請求至Tomcat。
第一種方式,應該效率高,畢竟Tomcat也是Apache家的產品,整合起來相當穩定容易。
第二種方式,通用性強,不僅可以轉發到Tomcat,還可以轉發到任意的HTTP伺服器程式,如IIS,另外的Apache例項。
根據個人愛好,我選擇了第二種方式。
解決方案
首先讓Tomcat偵聽8080埠。
然後修改httpd.conf。
# 載入轉發模組
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
# 把對zzz.com的訪問全部轉發給Tomcat
<VirtualHost *>
ServerAdmin zzz@126.com
ServerName zzz.com
ServerAlias www.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
這樣當用戶訪問http://www.zzz.com的時候,Apache就會代替使用者進而訪問http://localhost:8080,並把取回的http資料再轉發給使用者。這也就是Apache的逆向代理功能,這個代理的過程對瀏覽器客戶來說是不可感知的,某種程度上也保護和隱藏了Tomcat服務(因為Apache是通過內網http://127.0.0.1:8080訪問Tomcat服務的,http://www.zzz.com:8080對外部網際網路並不可見)。
與逆向代理(Reverse Proxy)相對應的是Apache的正向代理(Forward Proxy)功能,它需要瀏覽器端設定代理伺服器。
將來擴充套件
這種方案其實具有很強的擴充套件性,對於缺少公網IP的Web伺服器來說非常有意義。比如將來某天還需要部署一個基於IIS的網站。該網站域名為 aaa.com,執行在一個內網Windows機器上,IP地址為172.16.35.220,IIS偵聽在80埠上。那麼就可以通過Apache的逆向代理功能來部署。
<VirtualHost *>
ServerAdmin aaa@126.com
ServerName aaa.com
ServerAlias www.aaa.com
ProxyPass / http://172.16.35.220/
ProxyPassReverse / http://172.16.35.220/
#ProxyPreserveHost on 解決反向代理獲取不到真實地址和域名
ProxyPreserveHost on
</VirtualHost>