温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Tomcat多虚拟主机配置及原理什么

发布时间:2021-12-03 16:20:42 来源:亿速云 阅读:140 作者:柒染 栏目:大数据

这篇文章将为大家详细讲解有关Tomcat多虚拟主机配置及原理什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

我们多数的Tomcat用户,对于Tomcat的使用基本使用都是部署应用,浏览器中进行应用的请求。而这个对应用请求的格式,是这个样子:

http://localhost:8080/Web

其中8080是Connector对应的监听端口,Web是对应请求的应用,而localhost就是本次的主角,对应的就是Tomcat中默认包含的一个虚拟主机,对应到Tomcat中的Host容器。

在Tomcat的配置文件server.xml中,默认包含这样的配置

Tomcat多虚拟主机配置及原理什么
默认情况下,我们所有的应用都部署到了这个虚拟主机上,所以前面对于应用的请求,也就都被Connector转到了localhost这个Host上。

我们再来看虚拟主机这个概念。其相对于实体主机,是在一个机器上虚拟出了多个可供不同站点运行的机制

在Tomcat中,如果要支持多虚拟主机,配置起来也比较简单,

  1. 在Engine的组件内,增加关于Host的配置信息就可以了。对应的各个属性,可以参考默认的localhost主机。

  2. 在操作系统的hosts文件中,增加你新创建的虚拟主机名称对应到IP的映射。

  3. 可以选择在当前主机中增加类似于AccessLog之类的组件。

  4. 重启Tomcat,使改动生效。

假设我们新增的虚拟主机名是remoteHost,此时在浏览器中,我们就可以用

http://remoteHost:port/Webapp

这种形式来访问应用了。

新增虚拟主机的应用部署,可以通过配置主机的appBase属性来指定。

当然,除以上配置外,在Engine容器上,是可以配置一个defaultHost,也就是在Connector把请求交给Engine后,如果对应的Host不能响应请求,就会被转到defaultHost来处理。

此时,你可能会发现,多个虚拟主机之间的应用是隔离的,就和我们要搭个网站购买空间一样,我们只能访问到自己主机对应的资源与内容。这种主机间应用的隔离,在Tomcat内是如何实现的呢?

我们知道,在Tomcat中,整个服务对外提供,是抽象为Service,在server.xml中对应到Service的配置,service的默认实现是StandardService。在实现中,包含这样一个Field的声明:

protected final MapperListener mapperListener =

            new MapperListener(mapper, this);

他本质上也相当于一个组件,根据LifeCycle的生命周期进行启动、停止等。以下是其对应的类声明:

public class MapperListener extends LifecycleMBeanBase

        implements ContainerListener, LifecycleListener

在Service的start方法中,也会对MapperListener的start进行调用,在mapperListener启动过程中,会将自己注册到Engine的listener中,后续容器的所有生命周期,都会通知到。这里就是观察者模式的使用。(参见这里:和Tomcat学设计模式 | 发布-订阅模式)

        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);

            }

        }

我们看到,在启动时,会将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中创建的另一个field。这里注册的Host,以及上面方法中对应的registerContext,都被添加到mapper中,用做后面请求处理时的解析。

这里的addHost,最主要的是做了这样一个操作

MappedHost[] newHosts = new MappedHost[hosts.length + 1];

        MappedHost newHost = new MappedHost(name, host);

        if (insertMap(hosts, newHosts, newHost)) {

            hosts = newHosts;

 }

后面注册Context时,方式基本一致。而到了应用请求解析时,则是类似下面的流程:(请求处理可以参考:和Tomcat学设计模式 | Facade模式与请求处理,Tomcat是如何处理请求参数的?)

在Connector将请求传递到CoyoteAdaptor时,会在请求头处理之后,对requestresponse对象做一些后处理,以此传递给peipeline,进行请求。

在这一过程中,会进行这样的一段处理:

connector.getService().getMapper().map(serverName, decodedURI,

                            version, request.getMappingData());


就会使用到前面为service关联的Mapper,以此根据request的mappingData进行判断,把请求URI和context建立映射。这个时候,前面说的注册的那些东西就要被用到了。

// 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;

        }

上面几处标红的地方,hosts就是前面注册Host时候变更的对象,defaultHostName是开始时提到的,为Engine配置的默认主机,如果在其它主机找不到资源时,使用它来响应。我们看到,应用的mapping,是以Host为基础,从这里再寻找其对应的ContextList的。所以不同主机的应用就被隔离开了。

以上,就是Tomcat内多虚拟主机配置,以及其内部应用隔离和注册的原理。

  1. 在应用部署阶段,就会根据主机以及之上部署的应用进行分别register

  2. 在应用请求时,再根据部署时建立的mapping关系,去寻找对应主机上的Context

  3. 可以为Engine进行defaultHost的配置,在特定主机上找不到资源时以此响应

关于Tomcat多虚拟主机配置及原理什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI