Tomcat 总体架构-源码组织

开篇

 这篇文章主要是将Tomcat的架构图从源码角度解析了一下,基本上就是把图和源码串联起来。


Tomcat 总体架构

Tomcat 总体架构-源码组织_第1张图片
Tomcat 总体架构


Catalina - 入口

  Catalina对象包含Server对象变量,在初始化过程中通过Digester注入Server来实现。

  • protected Server server = null
public class Catalina {

    protected boolean await = false;

    protected String configFile = "conf/server.xml";

    protected ClassLoader parentClassLoader = Catalina.class.getClassLoader();

    // Catalina包含StandardServer对象
    protected Server server = null;

    protected boolean useShutdownHook = true;

    protected Thread shutdownHook = null;

    protected boolean useNaming = true;

    protected boolean loaded = false;
}


Server - StandardServer

  StandardServer实现了Server接口和Lifecycle接口,核心变量如下:

  • port字段存储标签的port属性
  • shutdown字段存储标签的shutdown属性
  • Service services[]存储Server标签子标签的标签对象
  • private Service services[] = new Service[0]
public final class StandardServer extends LifecycleMBeanBase implements Server {

    public StandardServer() {

        super();
        // 省略相关代码
    }

    // 省略相关代码

    // 对比server.xml中标签的内容的port
    private int port = 8005;

    // 维护Service的对象,
    private Service services[] = new Service[0];

    private final Object servicesLock = new Object();
    
    // 对比server.xml中标签的内容的shutdown
    private String shutdown = "SHUTDOWN";

    // 省略相关代码
}


Service - StandardService

  StandardService实现了Server接口和Lifecycle接口,核心变量如下:

  • Connector connectors[] 变量保存监听的Connector对象。
  • ArrayList executors 变量保存多线程对象Executor对象。
  • Engine engine变量保存Service标签内部的Engine对象。
  • Mapper mapper变量保存Mapper对象。
  • MapperListener mapperListener变量保存MapperListener对象。
public class StandardService extends LifecycleMBeanBase implements Service {
    private String name = null;

    private Server server = null;

    protected final PropertyChangeSupport support = new PropertyChangeSupport(this);
    
    // 保存Service标签下的Connector对象
    protected Connector connectors[] = new Connector[0];

    private final Object connectorsLock = new Object();
    
    // 保存Service的线程池Executor对象
    protected final ArrayList executors = new ArrayList<>();
    
    // 保存Service的Engine对象
    private Engine engine = null;

    private ClassLoader parentClassLoader = null;

    protected final Mapper mapper = new Mapper();

    protected final MapperListener mapperListener = new MapperListener(this);


Engine - StandardEngine

  StandardEngine实现了Server接口和Lifecycle接口,核心变量在基类ContainerBase:

  • 基类ContainerBase的HashMap children保存对应的对象。
  • 基类ContainerBase的Realm realm对象保存标签对应的对象。
  • 基类ContainerBase的Pipeline pipeline保存调用链并保存Valve对象。
public class StandardEngine extends ContainerBase implements Engine {
    public StandardEngine() {

        super();
        // 省略相关代码
    }

    private String defaultHost = null;

    private Service service = null;

    private String jvmRouteId;
}


public abstract class ContainerBase extends LifecycleMBeanBase implements Container {

    // 保存Host对象
    protected final HashMap children = new HashMap<>();

    protected int backgroundProcessorDelay = -1;

    protected final List listeners = new CopyOnWriteArrayList<>();

    protected Cluster cluster = null;

    private final ReadWriteLock clusterLock = new ReentrantReadWriteLock();

    protected String name = null;

    protected Container parent = null;

    protected ClassLoader parentClassLoader = null;

    protected final Pipeline pipeline = new StandardPipeline(this);
    // 保存Realm对象
    private volatile Realm realm = null;

    private final ReadWriteLock realmLock = new ReentrantReadWriteLock();

    protected boolean startChildren = true;

    private Thread thread = null;

    private volatile boolean threadDone = false;

    private int startStopThreads = 1;

    protected ThreadPoolExecutor startStopExecutor;
}


Host - StandardHost

  StandardEngine实现了Server接口和Lifecycle接口,部分变量在基类ContainerBase:

  • appBase 变量保存Host标签的appBase。
  • autoDeploy 变量保存Host标签的autoDeploy。
  • unpackWARs 变量保存Host标签的unpackWARs。
  • 基类ContainerBase的变量HashMap children保存Context变量。
  • 基类ContainerBase的Pipeline pipeline保存调用链并保存Valve对象。
public class StandardHost extends ContainerBase implements Host {

    public StandardHost() {

        super();
        pipeline.setBasic(new StandardHostValve());

    }

    private String[] aliases = new String[0];

    private final Object aliasesLock = new Object();

    private String appBase = "webapps";

    private volatile File appBaseFile = null;

    private String xmlBase = null;

    private volatile File hostConfigBase = null;

    private boolean autoDeploy = true;

    private String configClass = "org.apache.catalina.startup.ContextConfig";

    private String contextClass = "org.apache.catalina.core.StandardContext";

    private boolean deployOnStartup = true;

    private boolean deployXML = !Globals.IS_SECURITY_ENABLED;

    private boolean copyXML = false;

    private String errorReportValveClass = "org.apache.catalina.valves.ErrorReportValve";

    private boolean unpackWARs = true;

    private String workDir = null;

    private boolean createDirs = true;

    private final Map childClassLoaders = new WeakHashMap<>();

    private Pattern deployIgnore = null;

    private boolean undeployOldVersions = false;

    private boolean failCtxIfServletStartFails = false;
}



public abstract class ContainerBase extends LifecycleMBeanBase implements Container {

    // 保存Context对象
    protected final HashMap children = new HashMap<>();

    protected int backgroundProcessorDelay = -1;

    protected final List listeners = new CopyOnWriteArrayList<>();

    protected Cluster cluster = null;

    private final ReadWriteLock clusterLock = new ReentrantReadWriteLock();

    protected String name = null;

    protected Container parent = null;

    protected ClassLoader parentClassLoader = null;

    protected final Pipeline pipeline = new StandardPipeline(this);
    // 保存Realm对象
    private volatile Realm realm = null;

    private final ReadWriteLock realmLock = new ReentrantReadWriteLock();

    protected boolean startChildren = true;

    private Thread thread = null;

    private volatile boolean threadDone = false;

    private int startStopThreads = 1;

    protected ThreadPoolExecutor startStopExecutor;
}


Context - StandardContext

  StandardEngine实现了Server接口和Lifecycle接口,部分变量如下:

  • 在context容器中可以定义非常多的属性,详细内容见官方手册。
  • wrapperClass:实现wrapper容器的类,wrapper用于管理该context中的servlet,该类必须实现org.apache.catalina.Wrapper接口,如果不指定该属性则采用默认的标准类。
  • 基类ContainerBase的Pipeline pipeline保存调用链并保存Valve对象。
public class StandardContext extends ContainerBase implements Context, 
NotificationEmitter {

    // 省略相关代码

    private String wrapperClassName = StandardWrapper.class.getName();
    private Class wrapperClass = null;
}


Wrapper - StandardWrapper

 StandardWrapper实现了StandardWrapper接口用以处理servlet请求。

public class StandardWrapper extends ContainerBase
    implements StandardWrapper, Wrapper, NotificationEmitter {

    protected static final String[] DEFAULT_SERVLET_METHODS = 
                          new String[] {"GET", "HEAD", "POST" };


    public StandardWrapper() {

        super();
        swValve=new StandardWrapperValve();
        pipeline.setBasic(swValve);
        broadcaster = new NotificationBroadcasterSupport();

    }

    protected long available = 0L;
    protected final NotificationBroadcasterSupport broadcaster;
    protected final AtomicInteger countAllocated = new AtomicInteger(0);
    protected final StandardWrapperFacade facade = new StandardWrapperFacade(this);
    protected volatile Servlet instance = null;
    protected volatile boolean instanceInitialized = false;
    protected int loadOnStartup = -1;
    protected final ArrayList mappings = new ArrayList<>();
    protected HashMap parameters = new HashMap<>();
    protected HashMap references = new HashMap<>();
    protected String runAs = null;
    protected long sequenceNumber = 0;
    protected String servletClass = null;
    protected volatile boolean singleThreadModel = false;
    protected volatile boolean unloading = false;
    protected int maxInstances = 20;
    protected int nInstances = 0;
    protected Stack instancePool = null;
    protected long unloadDelay = 2000;
    protected boolean isJspServlet;
    protected ObjectName jspMonitorON;
    protected boolean swallowOutput = false;
    protected StandardWrapperValve swValve;
    protected long loadTime=0;
    protected int classLoadTime=0;
    protected MultipartConfigElement multipartConfigElement = null;
    protected boolean asyncSupported = false;
    protected boolean enabled = true;
    private boolean overridable = false;

    protected static Class[] classType = new Class[]{ServletConfig.class};

    private final ReentrantReadWriteLock parametersLock =
            new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock mappingsLock =
            new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock referencesLock =
            new ReentrantReadWriteLock();
}


Executor - StandardThreadExecutor

  Tomcat自定义Executor接口,继承自juc包下的Executor接口,增加getName()接口。

public interface Executor extends java.util.concurrent.Executor, Lifecycle {

    public String getName();

    void execute(Runnable command, long timeout, TimeUnit unit);
}



  Tomcat自定义ThreadPoolExecutor类,继承自juc包下的ThreadPoolExecutor接口,重写execute()方法。

public class ThreadPoolExecutor extends java.util.concurrent.ThreadPoolExecutor {

    private final AtomicInteger submittedCount = new AtomicInteger(0);
    private final AtomicLong lastContextStoppedTime = new AtomicLong(0L);
    private final AtomicLong lastTimeThreadKilledItself = new AtomicLong(0L);

    private long threadRenewalDelay = Constants.DEFAULT_THREAD_RENEWAL_DELAY;

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        prestartAllCoreThreads();
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory,
            RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        prestartAllCoreThreads();
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new RejectHandler());
        prestartAllCoreThreads();
    }

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new RejectHandler());
        prestartAllCoreThreads();
    }

    @Override
    public void execute(Runnable command) {
        execute(command,0,TimeUnit.MILLISECONDS);
    }

    public void execute(Runnable command, long timeout, TimeUnit unit) {
        submittedCount.incrementAndGet();
        try {
            super.execute(command);
        } catch (RejectedExecutionException rx) {
            if (super.getQueue() instanceof TaskQueue) {
                final TaskQueue queue = (TaskQueue)super.getQueue();
                try {
                    if (!queue.force(command, timeout, unit)) {
                        submittedCount.decrementAndGet();
                        throw new RejectedExecutionException("Queue capacity is full.");
                    }
                } catch (InterruptedException x) {
                    submittedCount.decrementAndGet();
                    throw new RejectedExecutionException(x);
                }
            } else {
                submittedCount.decrementAndGet();
                throw rx;
            }

        }
    }
}



  Tomcat的StandardThreadExecutor实现Lifecycle接口并实现自定义的Executor接口。

  • StandardThreadExecutor的executor对象是自定义的ThreadPoolExecutor对象。
  • 自定义的ThreadPoolExecutor对象是在startInternal()方法内部初始化,自定义线程工厂以及任务队列
  • StandardThreadExecutor实现了自定义Executor接口并在execute()方法执行自定义ThreadPoolExecutor的方法。
public class StandardThreadExecutor extends LifecycleMBeanBase
        implements Executor, ResizableExecutor {

    protected int threadPriority = Thread.NORM_PRIORITY;
    protected boolean daemon = true;
    protected String namePrefix = "tomcat-exec-";
    protected int maxThreads = 200;
    protected int minSpareThreads = 25;
    protected int maxIdleTime = 60000;
    protected ThreadPoolExecutor executor = null;
    protected String name;
    protected boolean prestartminSpareThreads = false;
    protected int maxQueueSize = Integer.MAX_VALUE;
    protected long threadRenewalDelay = org.apache.tomcat.util.threads.Constants.DEFAULT_THREAD_RENEWAL_DELAY;
    private TaskQueue taskqueue = null;

    public StandardThreadExecutor() {
        //empty constructor for the digester
    }


    @Override
    protected void initInternal() throws LifecycleException {
        super.initInternal();
    }

    @Override
    protected void startInternal() throws LifecycleException {

        taskqueue = new TaskQueue(maxQueueSize);
        TaskThreadFactory tf = new TaskThreadFactory(namePrefix,daemon,getThreadPriority());
        // 自定义ThreadPoolExecutor
        executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
        executor.setThreadRenewalDelay(threadRenewalDelay);
        if (prestartminSpareThreads) {
            executor.prestartAllCoreThreads();
        }
        taskqueue.setParent(executor);

        setState(LifecycleState.STARTING);
    }

    @Override
    public void execute(Runnable command, long timeout, TimeUnit unit) {
        if ( executor != null ) {
            executor.execute(command,timeout,unit);
        } else {
            throw new IllegalStateException("StandardThreadExecutor not started.");
        }
    }


    @Override
    public void execute(Runnable command) {
        if ( executor != null ) {
            try {
                executor.execute(command);
            } catch (RejectedExecutionException rx) {
                //there could have been contention around the queue
                if ( !( (TaskQueue) executor.getQueue()).force(command) ) throw new RejectedExecutionException("Work queue full.");
            }
        } else throw new IllegalStateException("StandardThreadPool not started.");
    }
}


Connector & ProtocolHandler & AbstractEndpoint

Connector的核心变量如下

  • 协议处理接口ProtocolHandler protocolHandler。
  • Coyote adapter 的 Adapter adapter。
public class Connector extends LifecycleMBeanBase  {

    public Connector() {
        this(null);
    }

    public Connector(String protocol) {
        setProtocol(protocol);

        ProtocolHandler p = null;
        try {
            Class clazz = Class.forName(protocolHandlerClassName);
            p = (ProtocolHandler) clazz.getConstructor().newInstance();
        } catch (Exception e) {
            log.error(sm.getString(
                    "coyoteConnector.protocolHandlerInstantiationFailed"), e);
        } finally {
            this.protocolHandler = p;
        }

    protected Service service = null;
    protected boolean allowTrace = false;
    protected long asyncTimeout = 30000;
    protected boolean enableLookups = false;
    protected boolean xpoweredBy = false;
    protected int port = -1;
    protected String proxyName = null;
    protected int proxyPort = 0;
    protected int redirectPort = 443;
    protected String scheme = "http";
    protected boolean secure = false;
    private int maxCookieCount = 200;
    protected int maxParameterCount = 10000;
    protected int maxPostSize = 2 * 1024 * 1024;
    protected int maxSavePostSize = 4 * 1024;
    protected String parseBodyMethods = "POST";
    protected HashSet parseBodyMethodsSet;
    protected boolean useIPVHosts = false;
    protected String protocolHandlerClassName =
        "org.apache.coyote.http11.Http11NioProtocol";

    // 协议处理接口 Coyote protocol handler.
    protected final ProtocolHandler protocolHandler;
    // Coyote adapter.
    protected Adapter adapter = null;

    protected String URIEncoding = null;
    protected String URIEncodingLower = null;
    private Charset uriCharset = StandardCharsets.UTF_8;
    protected boolean useBodyEncodingForURI = false;


    protected static final HashMap replacements = new HashMap<>();
    static {
        replacements.put("acceptCount", "backlog");
        replacements.put("connectionLinger", "soLinger");
        replacements.put("connectionTimeout", "soTimeout");
        replacements.put("rootFile", "rootfile");
    }
}



ProtocolHandler的核心变量如下

  • ProtocolHandler的内部包含AbstractEndpoint endpoint负责监听连接。
public abstract class AbstractProtocol implements ProtocolHandler,
        MBeanRegistration {

    private static final StringManager sm = StringManager.getManager(AbstractProtocol.class);

    private static final AtomicInteger nameCounter = new AtomicInteger(0);

    protected ObjectName rgOname = null;

    private int nameIndex = 0;

    private final AbstractEndpoint endpoint;

    private Handler handler;

    private final Set waitingProcessors =
            Collections.newSetFromMap(new ConcurrentHashMap());

    private AsyncTimeout asyncTimeout = null;
}

你可能感兴趣的:(java)