其實配置虛擬主機的文章很多,Apusic應(yīng)用服務(wù)器管理文檔中已有專門的描述,我這里寫的最重要是虛擬主機有啥用,是否還有其他解決方案。
這篇文章是從最近的工作中得來的,最初需求是要配置虛擬主機,結(jié)果采用的是寫了一段代碼進行代替。兩種方法不分高低,可能對于喜歡規(guī)范的朋友會鄙視我的變通方式,覺得俺的東西不遵守規(guī)范,給未來又留下多少隱患之類,但是我認(rèn)為寫代碼對國內(nèi)項目來說,由于都是程序員現(xiàn)場實施,因此未來的變化更加好控制。最后,我還會提供一種更為復(fù)雜,但是更為先進的虛擬機方式就是Apache+Apusic整合的方式,這樣結(jié)果會更靈活,當(dāng)然維護成本也就更高。
先介紹為什么要配虛擬主機,給客戶到底帶來什么價值呢?
一般是主機提供商喜歡用虛擬主機,他們將一個服務(wù)器資源分配給許多客戶使用,每個客戶有自己的域名,有權(quán)訪問自己虛擬主機部署的應(yīng)用。而現(xiàn)在政府客戶為了突出部門的獨立性也喜歡申請單獨的域名,通過不同的域名訪問部門自己的門戶系統(tǒng),但是這些應(yīng)用部署在統(tǒng)一對外的服務(wù)器上,甚至由一個J2EE應(yīng)用提供不同的門戶。
那么虛擬主機又是如何運作的呢?
虛擬主機首先是域名的不同,域名由DNS服務(wù)器解析成IP地址。如果那些應(yīng)用都部署在統(tǒng)一對外的服務(wù)器上,那么不同的域名將會解析成相同的IP地址返回給瀏覽器。瀏覽器依據(jù)這個IP地址訪問應(yīng)用服務(wù)器,并且會把訪問用的URL帶在HTTP頭中。如果訪問的應(yīng)用都使用相同的路徑(<context-root>/</context-root>),這些應(yīng)用就會在部署時發(fā)生沖突。為了解決這樣的沖突,應(yīng)用服務(wù)器中間件就提供了虛擬主機的方式,等于在一個應(yīng)用服務(wù)器中間件上可以虛擬出好幾個計算機,當(dāng)然部署相同上下文名稱的應(yīng)用也就不會再有問題。應(yīng)用服務(wù)器通過判斷HTTP頭中的URL來決定采用哪個虛擬主機中的應(yīng)用提供服務(wù)。
Apusic如何配置虛擬主要呢?
修改config/server.xml文件增加virtual-host參數(shù)就可以實現(xiàn)。這個實驗在本機也可以測試,測試過程如下:
1. 修改Windows/system32/drivers/etc/hosts. 文件,模仿localhost增加
?127.0.0.1?localhost1
?127.0.0.1?localhost2
2. 與applications目錄平級建立一個webapp目錄(名稱隨意,主要是避免放在applications目錄下,應(yīng)用被自動發(fā)布),復(fù)制applications目錄下的default目錄到webapp目錄中,并將目錄改成default1和default2
3. 修改server.xml文件,模仿default增加
? <application name="default1" base="webapp/default1" virtual-host="localhost1" start="auto"/>
? <application name="default2" base="webapp/default2" virtual-host="localhost2" start="auto"/>
4. 啟動apusic應(yīng)用服務(wù)器,你會發(fā)現(xiàn)有相同上下文Context Root的應(yīng)用被啟動。
5. 修改每個應(yīng)用的index.jsp文件,增加區(qū)分標(biāo)識,然后通過不同的URL(http://localhost:6888或http://localhost1:6888)訪問,會得到不同應(yīng)用的顯示頁面。
現(xiàn)在大家已經(jīng)成功完成虛擬主機的配置,但是使用虛擬主機存在什么問題呢?
1. 如果這些應(yīng)用是相互獨立的,那么他們之間的會話(Session)數(shù)據(jù)是無法共享的,應(yīng)用相關(guān)的頁面和風(fēng)格無法共享,用戶需要維護多個應(yīng)用增加了維護成本;
2. 如果這些頁面統(tǒng)一跳轉(zhuǎn)到一個應(yīng)用的不同目錄下,那么瀏覽器的URL就會變成部署應(yīng)用的虛擬主機域名,但是這個可能不是用戶所希望的。
新的用戶需求,因為用戶其實只采購了一個應(yīng)用,但是希望不同的域名有不同的門戶主頁,于是我的解決方案是應(yīng)用只有一個,在應(yīng)用里面建立default1和default2目錄,那么用戶訪問服務(wù)器時,系統(tǒng)會根據(jù)URL的不同進行跳轉(zhuǎn),判斷URL的代碼如下:
<html>
<head>
</head>
<body>
<script type="text/javascript">
var aHost=window.location.hostname; //取得訪問應(yīng)用服務(wù)器使用的域名
if (aHost=="localhost1")
?window.location.href="http://localhost:6888/default1";
else if (aHost=="localhost2")
?window.location.href="http://localhost:6888/default2";
else alert("nothing happen!");
</script>
</body>
</html>
這種訪問,無論如何跳轉(zhuǎn)域名都不會發(fā)生改變,而且跳轉(zhuǎn)到其他門戶時會話數(shù)據(jù)可以共享,簡化了SSO(單點登錄)的開發(fā)難度。但是,這種方式也有缺陷就是訪問時上下文必須不同,而且無法讓所有的域名使用相同的上下文,特別是都使用根目錄。因此,采用哪種方式看用戶的需要。
但是,維護者可能還是覺得復(fù)雜,因為要動底層代碼,是否還有完全配置的解決方案嗎?
有!那就是用Apache+Apusic配置虛擬主機,整個操作過程如下:
1. 先在Apusic的默認(rèn)default應(yīng)用中增加兩個目錄default1和default2,修改index.jsp文件方便顯示后區(qū)分;
2. 修改Apache的配置文件httpd.conf,增加虛擬主機的配置,通過Apache的虛擬主機+代理跳轉(zhuǎn)的方式,提供對虛擬主機的支持,增加部分如下:
#以下增加的模塊部分無用,只是我沒時間查證,所以都打開了。
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
NameVirtualHost *:8080
<VirtualHost *:8080>
?ProxyPreserveHost On
?ServerAdmin zhuyuanxiang@apusic.com
?ServerName localhost
?ProxyPass / http://localhost:6888/
?ProxyPassreverse? / http://localhost:6888/
</VirtualHost>
<VirtualHost *:8080>
?ProxyPreserveHost On
?ServerAdmin zhuyuanxiang@apusic.com
?ServerName localhost1
?ProxyPass / http://localhost:6888/default1/
?ProxyPassreverse? / http://localhost:6888/default1/
</VirtualHost>
<VirtualHost *:8080>
?ProxyPreserveHost On
?ServerAdmin zhuyuanxiang@apusic.com
?ServerName localhost2
?ProxyPass / http://localhost:6888/default2/
?ProxyPassreverse? / http://localhost:6888/default2/
</VirtualHost>
3. 啟動apusic應(yīng)用服務(wù)器,通過http://localhost:8080和http://localhost1:8080和http://localhost2:8080就可以得到不同的展示頁面。
(后兩個頁面顯示不正確,因為它們的圖片路徑不正確,在后臺他們其實使用的不是前臺顯示的路徑,因此服務(wù)器無法找到圖片)
這個就使不同虛擬主機都以根路徑的方式顯示不同的門戶,同時在后臺應(yīng)用服務(wù)器上可以共享應(yīng)用,但是同時也帶來了潛在的維護成本和系統(tǒng)風(fēng)險。
那么到底采用什么樣的方式配置虛擬主機呢?
其實這個需要實際場景來決定,以下幾個條件可以參考:
1. 是否需要共享應(yīng)用?
2. 是否需要都使用根路徑?
3. 是否需要通過Apache來提供負(fù)載均衡?
根本目標(biāo)是開發(fā)和維護簡單化,夠用就是最好的,做技術(shù)的朋友最怕追求技術(shù)先進性。
參考文獻:
1. mod_proxy - Apache 2.2 中文版參考手冊,
http://doc.chinahtml.com/Manual/ApacheManual/mod/mod_proxy.html
2. 基于反相代理的Web緩存加速
http://www.chedong.com/tech/cache.html