tomcat原理解析(二):整体架构
来源:互联网 发布:ubuntu 电脑散热器响 编辑:程序博客网 时间:2024/04/26 08:58
一 整体结构
前面tomcat实现原理(一)里面描述了整个tomcat接受一个http请求的简单处理,这里面我们讲下整个tomcat的架构,以便对整体结构有宏观的了解。tomat里面由很多个容器结合在一起,主要有server,service,context,host,engine,wrapper,connector这7个容器来组装。当然了tomcat里面还有其它容器这里就不一一列举,因为我只看重点的。这7个容器存着父子关系,即可以通过当前容器找自己的父容器和自己的子容器。说到这我画了一个简单的结构图,让这种关系更加直观。如下:
根据图可以看出server是最外层的一个容器,它里面可以包含了Service容器,Service容器里面又包含了Connector和Engine,Engine容器里面又包含了Host,Host容器包含Context,Context容器包含Wrapper容器。就好比一个人有最外层的躯体,躯体里面有心脏,肺,胃,肾脏等等很多个个功能器件。
二 组件描述
这里主要通过tomcat的源码来分析这7个容器是通过什么样的机制来组织在一起的,相互的包含的关系怎么处理。
1.server组件
server就像一个架子,很多其它子容器都装配在这个架子上。同时这个容器又暴露了一些入口对外提供服务。比如初始化服务,启动服务,停止服务等。源码中的server是一个接口,如下图:
查看Server接口类它还继承着Lifecycle接口,详情如下图:
Lifecycle接口控制着各个组件的生命周期,比如接口中的抽象方法init()初始化,start()启动,stop()停止,destory()销毁。 Server的标准实现类为StandardServer,细读StandardServer里面的接口addService,findServices的实现代码,可以看出这Service和 Server有着关联,Server可以有多个Service以数组的形式保存在其中。
public void addService(Service service) { service.setServer(this); synchronized (services) { Service results[] = new Service[services.length + 1]; System.arraycopy(services, 0, results, 0, services.length); results[services.length] = service; services = results; if (getState().isAvailable()) { try { service.start(); } catch (LifecycleException e) { // Ignore } } // Report this property change to interested listeners support.firePropertyChange("service", null, service); } }
1.将设置进来的Service 对象设置父组件为Server
2.重新构建了一个Service数组,然后将老的Service拷贝到新的数组中,同时追加新的Service组件
3.根据当前组件的生命状态,判断新加入的组件是否需要启动
2.Service组件
service接口它也继承Lifecycle接口。 前面说过了service组件的父组件是server组件,结构如下图:
它的标准实现是StandardService类,查看接口抽象方法addConnector的具体实现可以看出通过它可以给service容器添加connector容器,这里的connector就主要负责接收浏览器客户端发过来的http请求,仔细看里面的源码可以发现它接到请求时生成了一个socket对象,并将这个socket对象放入了一个线程中,同时线程会存入一个线程池来处理这次响应,并根据请求的详情信息来定位响应资源,响应的资源通过Engine容器给出。它就像浏览器和 Engine容器的桥梁,具体如何响应请求的会通过后面的章节来细说。先看是怎么将connector容器绑定到service中。 如下面代码:
public void addConnector(Connector connector) { synchronized (connectors) { connector.setService(this); Connector results[] = new Connector[connectors.length + 1]; System.arraycopy(connectors, 0, results, 0, connectors.length); results[connectors.length] = connector; connectors = results; if (getState().isAvailable()) { try { ((Lifecycle) connector).start(); } catch (LifecycleException e) { log.error("Connector.start", e); } } // Report this property change to interested listeners support.firePropertyChange("connector", null, connector); } }
1.给当前入去的Connector主键设置父容器service.
2.根据原有Connector集合的大小加上新加入的容器,从新构建了一个Connector数组。
3.将旧的数据拷贝到新的容器数组中,再添加新加的容器
4.然后根据当前容器的生命状态判断是否要启动新加入的容器
这里存放connector组件为什么用数组而不用List来存放不是太明白。感觉跟server管理service组件操作一样。看完所有的抽象接口是不是感觉有些奇怪,按照前面给的整体架构图怎么没看到给Service添加Engine组件的入口。查看Engine的标准实现类StandardEngine其实是实现了Container接口的,所以这里应该是通过setContainer接口设置进去的,其源码如下:
public void setContainer(Container container) { Container oldContainer = this.container; if ((oldContainer != null) && (oldContainer instanceof Engine)) ((Engine) oldContainer).setService(null); this.container = container; if ((this.container != null) && (this.container instanceof Engine)) ((Engine) this.container).setService(this); if (getState().isAvailable() && (this.container != null)) { try { this.container.start(); } catch (LifecycleException e) { // Ignore } } if (getState().isAvailable() && (oldContainer != null)) { try { oldContainer.stop(); } catch (LifecycleException e) { // Ignore } } // Report this property change to interested listeners support.firePropertyChange("container", oldContainer, this.container); }1.将原有的Container(Engine)对象 的父对象置为空
2.同时将旧的Container对象覆盖掉,变成新注入的Container对象
3.同时根据当前组件的生命周期来判断是否将新注入的容器启动
3.Engine组件
Engine接口类为该组件的抽象接口,它继承Container接口跟前面描述的两个组件似乎有些不一样,查看源码后发现Container接口也继承了Lifecycle接口。Engine结构如下图:
它的标准实现是StandardEngine类,查setService接口的具体实现,service组件设置进Engine组件中,让两者之间关联。怎么没有看到添加子组件的入口呢?我们查看StandardEngine实现类中,它继承了ContainerBase类,而这个类实现了Container接口。在StandardEngine类中看到了addChild方法的实现 如下代码:
@Override public void addChild(Container child) { if (!(child instanceof Host)) throw new IllegalArgumentException (sm.getString("standardEngine.notHost")); super.addChild(child); }
通过这个方法来为Engine添加子组件
1.判断当前传入的组件是否是Host类型的,否则抛异常
2.调用服务类中的addChild方法,同时将child变量传递到父类中处理,我们继续看父类ContainerBase中的代码。
public void addChild(Container child) { if (Globals.IS_SECURITY_ENABLED) { PrivilegedAction<Void> dp = new PrivilegedAddChild(child); AccessController.doPrivileged(dp); } else { addChildInternal(child); } } private void addChildInternal(Container child) { if( log.isDebugEnabled() ) log.debug("Add child " + child + " " + this); synchronized(children) { if (children.get(child.getName()) != null) throw new IllegalArgumentException("addChild: Child name '" + child.getName() + "' is not unique"); child.setParent(this); // May throw IAE children.put(child.getName(), child); // Start child if ((getState().isAvailable() || LifecycleState.STARTING_PREP.equals(getState())) && startChildren) { boolean success = false; try { child.start(); success = true; } catch (LifecycleException e) { log.error("ContainerBase.addChild: start: ", e); throw new IllegalStateException ("ContainerBase.addChild: start: " + e); } finally { if (!success) { children.remove(child.getName()); } } } fireContainerEvent(ADD_CHILD_EVENT, child); } }最终它调用了addChildInternal方法来处理。
child.setParent(this);
children.put(child.getName(), child);
1.这里传入host子组件的同时,给host子组件设置了父组件
2.将子组件保存在children变量中,这里的children其实就是个HashMap对象。
看到这里也就明白了,所有继承ContainerBase类的组件在添加子组件都是依赖父类中的MAP对象来保存的.
4.Host组件
Host类为该组件的接口定义,也继承了Container类,它的标准实现是StandardHost类,继承ContainerBase类。host结构如下图所示:
因为该标准实现类StandardHost也继承了ContainerBase类,所以该组件的子组件添加也依赖父类中的Map来保存,跟Engine组件管理子组件是一样的。每一个HOST相当于一个主机,并负责展开和运行多个部署进去的war包。每个主机下面有多个部署的应用,一个应用就对应着一个Context。通过context将多个应用分隔开。所以host的子组件就是context,在通过ContainerBase类的addChild方法来添加context子容器的同时也给它设置了父容器host对象。
5.Context容器
context接口继承了Container,StandardContext类为是Context的标准实现,它也继承了ContainerBase类,所以给改容器注入子容器也是通过containerBase类中的addaddChild来处理的。Context容器代表着一个servlet容器,它为servlet运行提供环境。context管理着里面servlet实例,servlet实例在context中以Wrapper形式存在。那么一个http请求是怎么找到对应的servlet实例的呢?后面章节再来详细描述
6.Wrapper容器
Wrapper接口类也继承Container类,它的标准实现类是StandardWrapper,也继承了ContainerBase类。因为Wrapper容器是最底层的容器了,所以它不存在子容器。Wrapper 代表一个Servlet,它负责管理一个 Servlet,包括的 Servlet的装载、初始化、执行以及资源回收。
三 组件相关类结构
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.catalina.util;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleException;import org.apache.catalina.LifecycleListener;import org.apache.catalina.LifecycleState;import org.apache.juli.logging.Log;import org.apache.juli.logging.LogFactory;import org.apache.tomcat.util.res.StringManager;/** * Base implementation of the {@link Lifecycle} interface that implements the * state transition rules for {@link Lifecycle#start()} and * {@link Lifecycle#stop()} */public abstract class LifecycleBase implements Lifecycle { private static Log log = LogFactory.getLog(LifecycleBase.class); private static StringManager sm = StringManager.getManager("org.apache.catalina.util"); /** * Used to handle firing lifecycle events. * TODO: Consider merging LifecycleSupport into this class. */ private LifecycleSupport lifecycle = new LifecycleSupport(this); /** * The current state of the source component. */ private volatile LifecycleState state = LifecycleState.NEW; /** * {@inheritDoc} */ @Override public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } /** * {@inheritDoc} */ @Override public LifecycleListener[] findLifecycleListeners() { return lifecycle.findLifecycleListeners(); } /** * {@inheritDoc} */ @Override public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } /** * Allow sub classes to fire {@link Lifecycle} events. * * @param type Event type * @param data Data associated with event. */ protected void fireLifecycleEvent(String type, Object data) { lifecycle.fireLifecycleEvent(type, data); } public synchronized final void init() throws LifecycleException { if (!state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.INIT_EVENT); } //1.实现初始化的方法,最终是调用了当前类的initInternal方法,发现initInternal抽象的 initInternal(); setState(LifecycleState.INITIALIZED); } protected abstract void initInternal() throws LifecycleException; /** * {@inheritDoc} */ @Override public synchronized final void start() throws LifecycleException { if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) || LifecycleState.STARTED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyStarted", toString())); } return; } if (state.equals(LifecycleState.NEW)) { init(); } else if (!state.equals(LifecycleState.INITIALIZED) && !state.equals(LifecycleState.STOPPED)) { invalidTransition(Lifecycle.BEFORE_START_EVENT); } setState(LifecycleState.STARTING_PREP); try { //2.实现初始化的方法,最终是调用了当前类的startInternal方法,发现startInternal抽象的 startInternal(); } catch (LifecycleException e) { setState(LifecycleState.FAILED); throw e; } if (state.equals(LifecycleState.FAILED) || state.equals(LifecycleState.MUST_STOP)) { stop(); } else { // Shouldn't be necessary but acts as a check that sub-classes are // doing what they are supposed to. if (!state.equals(LifecycleState.STARTING)) { invalidTransition(Lifecycle.AFTER_START_EVENT); } setState(LifecycleState.STARTED); } } /** * Sub-classes must ensure that: * <ul> * <li>the {@link Lifecycle#START_EVENT} is fired during the execution of * this method</li> * <li>the state is changed to {@link LifecycleState#STARTING} when the * {@link Lifecycle#START_EVENT} is fired * </ul> * * If a component fails to start it may either throw a * {@link LifecycleException} which will cause it's parent to fail to start * or it can place itself in the error state in which case {@link #stop()} * will be called on the failed component but the parent component will * continue to start normally. * * @throws LifecycleException */ protected abstract void startInternal() throws LifecycleException; /** * {@inheritDoc} */ @Override public synchronized final void stop() throws LifecycleException { if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) || LifecycleState.STOPPED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyStopped", toString())); } return; } if (state.equals(LifecycleState.NEW)) { state = LifecycleState.STOPPED; return; } if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED) && !state.equals(LifecycleState.MUST_STOP)) { invalidTransition(Lifecycle.BEFORE_STOP_EVENT); } setState(LifecycleState.STOPPING_PREP); //3.实现初始化的方法,最终是调用了当前类的stopInternal方法,发现stopInternal抽象的 stopInternal(); if (state.equals(LifecycleState.MUST_DESTROY)) { // Complete stop process first setState(LifecycleState.STOPPED); destroy(); } else { // Shouldn't be necessary but acts as a check that sub-classes are doing // what they are supposed to. if (!state.equals(LifecycleState.STOPPING)) { invalidTransition(Lifecycle.AFTER_STOP_EVENT); } setState(LifecycleState.STOPPED); } } /** * Sub-classes must ensure that: * <ul> * <li>the {@link Lifecycle#STOP_EVENT} is fired during the execution of * this method</li> * <li>the state is changed to {@link LifecycleState#STOPPING} when the * {@link Lifecycle#STOP_EVENT} is fired * </ul> * * @throws LifecycleException */ protected abstract void stopInternal() throws LifecycleException; public synchronized final void destroy() throws LifecycleException { if (LifecycleState.DESTROYED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString())); } return; } if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) && !state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.DESTROY_EVENT); } //4.实现初始化的方法,最终是调用了当前类的destroyInternal方法,发现destroyInternal抽象的 destroyInternal(); setState(LifecycleState.DESTROYED); } protected abstract void destroyInternal() throws LifecycleException; /** * {@inheritDoc} */ public LifecycleState getState() { return state; } /** * Provides a mechanism for sub-classes to update the component state. * Calling this method will automatically fire any associated * {@link Lifecycle} event. * * @param state The new state for this component */ protected synchronized void setState(LifecycleState state) { setState(state, null); } /** * Provides a mechanism for sub-classes to update the component state. * Calling this method will automatically fire any associated * {@link Lifecycle} event. * * @param state The new state for this component * @param data The data to pass to the associated {@link Lifecycle} event */ protected synchronized void setState(LifecycleState state, Object data) { if (log.isDebugEnabled()) { log.debug(sm.getString("lifecycleBase.setState", this, state)); } this.state = state; String lifecycleEvent = state.getLifecycleEvent(); if (lifecycleEvent != null) { fireLifecycleEvent(lifecycleEvent, data); } } private void invalidTransition(String type) throws LifecycleException { String msg = sm.getString("lifecycleBase.invalidTransition", type, toString(), state); throw new LifecycleException(msg); }}阅读以上LifecycleBase类中的源码,在第1,2,3,4处分别实现了init(),start(),stop(),destroy()等方法。分析其方法体中内容,实现代码最终还是调用了当前类中的initInternal(),startInternal(),stopInternal(),destroyInternal()等方法,而且这些方法还是抽象的。也就是说在执行这些方法时,最终是执行子类的具体实现。这貌似就是设计模式中的抽象模版方法模式哦!
四 总结
- tomcat原理解析(二):整体架构
- Tomcat源码解析(一):tomcat整体架构解析
- Tomcat整体架构(Tomcat源码阅读系列之二)
- Tomcat整体架构分析
- Tomcat整体架构浅析
- JVM原理之整体架构
- netfilter整体架构解析初步
- netfilter整体架构解析初步
- netfilter整体架构解析初步
- jQuery整体架构源码解析
- jQuery整体架构源码解析
- jQuery源码解析-整体架构
- levelDB之二:整体架构
- LevelDb之二:整体架构
- Tomcat探秘(3):tomcat整体架构
- [Tomcat剖析] 1 Tomcat整体架构
- JVM原理、架构—整体架构
- (二)Tomcat源码解析 - Tomcat架构详解
- 欢迎使用CSDN-markdown编辑器
- WARNING IPv4 forwarding is disabled. Networking will not work 解决办法: # vi /etc/sysctl.conf 或者 # vi /
- 搜狗大数据总监、Polarr 联合创始人关于深度学习的分享交流
- Android Studio 编写AIDL需要注意的点
- camera理论基础和工作原理
- tomcat原理解析(二):整体架构
- HDU 2066 一个人的旅行
- 如果让我重新设计一款Android App
- HTML5跨浏览器的补丁和功能
- oracle、游标相集合分页ch
- Git服务器配置
- Intellij idea 从SVN导出项目出现:cannot load supported fromats: cannot run program "SVN"
- Hibernate单表查询总结(上)
- Kafka API8 producer