伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Tomcat多虚拟主机配置及原理

来源:本站原创 浏览:209次 时间:2021-06-12

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


http://localhost:8080/Web


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


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



默认情况下,我们所有的应用都部署到了这个虚拟主机上,所以前面对于应用的请求,也就都被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进行调用,在mapperListen���ܾ���,����ʤ��er启动过程中,会将自己注册到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时,会在请求头处理之后,对request和response对象做一些后处理,以此传递给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的配置,在特定主机上找不到资源时以此响应


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net