您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Tomcat多虛擬主機(jī)配置及原理什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
我們多數(shù)的Tomcat用戶,對于Tomcat的使用基本使用都是部署應(yīng)用,瀏覽器中進(jìn)行應(yīng)用的請求。而這個對應(yīng)用請求的格式,是這個樣子:
http://localhost:8080/Web
其中8080是Connector對應(yīng)的監(jiān)聽端口,Web是對應(yīng)請求的應(yīng)用,而localhost就是本次的主角,對應(yīng)的就是Tomcat中默認(rèn)包含的一個虛擬主機(jī),對應(yīng)到Tomcat中的Host容器。
在Tomcat的配置文件server.xml中,默認(rèn)包含這樣的配置
默認(rèn)情況下,我們所有的應(yīng)用都部署到了這個虛擬主機(jī)上,所以前面對于應(yīng)用的請求,也就都被Connector轉(zhuǎn)到了localhost這個Host上。
我們再來看虛擬主機(jī)這個概念。其相對于實(shí)體主機(jī),是在一個機(jī)器上虛擬出了多個可供不同站點(diǎn)運(yùn)行的機(jī)制。
在Tomcat中,如果要支持多虛擬主機(jī),配置起來也比較簡單,
在Engine的組件內(nèi),增加關(guān)于Host的配置信息就可以了。對應(yīng)的各個屬性,可以參考默認(rèn)的localhost主機(jī)。
在操作系統(tǒng)的hosts文件中,增加你新創(chuàng)建的虛擬主機(jī)名稱對應(yīng)到IP的映射。
可以選擇在當(dāng)前主機(jī)中增加類似于AccessLog之類的組件。
重啟Tomcat,使改動生效。
假設(shè)我們新增的虛擬主機(jī)名是remoteHost,此時(shí)在瀏覽器中,我們就可以用
http://remoteHost:port/Webapp
這種形式來訪問應(yīng)用了。
新增虛擬主機(jī)的應(yīng)用部署,可以通過配置主機(jī)的appBase屬性來指定。
當(dāng)然,除以上配置外,在Engine容器上,是可以配置一個defaultHost,也就是在Connector把請求交給Engine后,如果對應(yīng)的Host不能響應(yīng)請求,就會被轉(zhuǎn)到defaultHost來處理。
此時(shí),你可能會發(fā)現(xiàn),多個虛擬主機(jī)之間的應(yīng)用是隔離的,就和我們要搭個網(wǎng)站購買空間一樣,我們只能訪問到自己主機(jī)對應(yīng)的資源與內(nèi)容。這種主機(jī)間應(yīng)用的隔離,在Tomcat內(nèi)是如何實(shí)現(xiàn)的呢?
我們知道,在Tomcat中,整個服務(wù)對外提供,是抽象為Service,在server.xml中對應(yīng)到Service的配置,service的默認(rèn)實(shí)現(xiàn)是StandardService。在實(shí)現(xiàn)中,包含這樣一個Field的聲明:
protected final MapperListener mapperListener =
new MapperListener(mapper, this);
他本質(zhì)上也相當(dāng)于一個組件,根據(jù)LifeCycle的生命周期進(jìn)行啟動、停止等。以下是其對應(yīng)的類聲明:
public class MapperListener extends LifecycleMBeanBase
implements ContainerListener, LifecycleListener
在Service的start方法中,也會對MapperListener的start進(jìn)行調(diào)用,在mapperListener啟動過程中,會將自己注冊到Engine的listener中,后續(xù)容器的所有生命周期,都會通知到。這里就是觀察者模式的使用。(參見這里:和Tomcat學(xué)設(shè)計(jì)模式 | 發(fā)布-訂閱模式)
Engine engine = (Engine) service.getContainer();
addListeners(engine); // 這里就是注冊
Container[] conHosts = engine.findChildren();
for (Container conHost : conHosts) {
Host host = (Host) conHost;
if (!LifecycleState.NEW.equals(host.getState())) {
// Registering the host will register the context and wrappers
registerHost(host);
}
}
我們看到,在啟動時(shí),會將Engine下所有的Host注冊一下。我們來看這里的注冊是在做些啥。
private void registerHost(Host host) {
String[] aliases = host.findAliases();
mapper.addHost(host.getName(), aliases, host);
for (Container container : host.findChildren()) {
if (container.getState().isAvailable()) {
registerContext((Context) container);
}
}
}
這里的mapper,是StandardService中創(chuàng)建的另一個field。這里注冊的Host,以及上面方法中對應(yīng)的registerContext,都被添加到mapper中,用做后面請求處理時(shí)的解析。
這里的addHost,最主要的是做了這樣一個操作
MappedHost[] newHosts = new MappedHost[hosts.length + 1];
MappedHost newHost = new MappedHost(name, host);
if (insertMap(hosts, newHosts, newHost)) {
hosts = newHosts;
}
后面注冊Context時(shí),方式基本一致。而到了應(yīng)用請求解析時(shí),則是類似下面的流程:(請求處理可以參考:和Tomcat學(xué)設(shè)計(jì)模式 | Facade模式與請求處理,Tomcat是如何處理請求參數(shù)的?)
在Connector將請求傳遞到CoyoteAdaptor時(shí),會在請求頭處理之后,對request和response對象做一些后處理,以此傳遞給peipeline,進(jìn)行請求。
在這一過程中,會進(jìn)行這樣的一段處理:
connector.getService().getMapper().map(serverName, decodedURI,
version, request.getMappingData());
就會使用到前面為service關(guān)聯(lián)的Mapper,以此根據(jù)request的mappingData進(jìn)行判斷,把請求URI和context建立映射。這個時(shí)候,前面說的注冊的那些東西就要被用到了。
// Virtual host mapping
MappedHost[] hosts = this.hosts;
MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
if (mappedHost == null) {
if (defaultHostName == null) {
return;
}
mappedHost = exactFind(hosts, defaultHostName);
if (mappedHost == null) {
return;
}
}
mappingData.host = mappedHost.object;
// Context mapping
ContextList contextList = mappedHost.contextList;
MappedContext[] contexts = contextList.contexts;
int pos = find(contexts, uri);
if (pos == -1) {
return;
}
上面幾處標(biāo)紅的地方,hosts就是前面注冊Host時(shí)候變更的對象,defaultHostName是開始時(shí)提到的,為Engine配置的默認(rèn)主機(jī),如果在其它主機(jī)找不到資源時(shí),使用它來響應(yīng)。我們看到,應(yīng)用的mapping,是以Host為基礎(chǔ),從這里再尋找其對應(yīng)的ContextList的。所以不同主機(jī)的應(yīng)用就被隔離開了。
以上,就是Tomcat內(nèi)多虛擬主機(jī)配置,以及其內(nèi)部應(yīng)用隔離和注冊的原理。
在應(yīng)用部署階段,就會根據(jù)主機(jī)以及之上部署的應(yīng)用進(jìn)行分別register
在應(yīng)用請求時(shí),再根據(jù)部署時(shí)建立的mapping關(guān)系,去尋找對應(yīng)主機(jī)上的Context
可以為Engine進(jìn)行defaultHost的配置,在特定主機(jī)上找不到資源時(shí)以此響應(yīng)
關(guān)于Tomcat多虛擬主機(jī)配置及原理什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。