Tomcat 总体架构-源码组织
开篇 这篇文章主要是将Tomcat的架构图从源码角度解析了一下,基本上就是把图和源码串联起来。 Tomcat 总体架构 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字段存储<server>标签的port属性 shutdown字段存储<server>标签的shutdown属性 Service services[]存储Server标签子标签的<Service>标签对象 private Service services[] = new Service[0] public final class StandardServer extends LifecycleMBeanBase implements Server { public StandardServer() { super(); // 省略相关代码 } // 省略相关代码 // 对比server.xml中<server>标签的内容的port private int port = 8005; // 维护Service的对象, private Service services[] = new Service[0]; private final Object servicesLock = new Object(); // 对比server.xml中<server>标签的内容的shutdown private String shutdown = "SHUTDOWN"; // 省略相关代码 } Service - StandardService StandardService实现了Server接口和Lifecycle接口,核心变量如下: Connector connectors[] 变量保存监听的Connector对象。 ArrayList<Executor> 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<Executor> 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<String, Container> children保存<Host>对应的对象。 基类ContainerBase的Realm 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<String, Container> children = new HashMap<>(); protected int backgroundProcessorDelay = -1; protected final List<ContainerListener> 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<String, Container> 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<ClassLoader, String> 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<String, Container> children = new HashMap<>(); protected int backgroundProcessorDelay = -1; protected final List<ContainerListener> 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<String> mappings = new ArrayList<>(); protected HashMap<String, String> parameters = new HashMap<>(); protected HashMap<String, String> 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<Servlet> 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<Runnable> workQueue, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); prestartAllCoreThreads(); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> 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<Runnable> workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new RejectHandler()); prestartAllCoreThreads(); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> 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<String> 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<String,String> replacements = new HashMap<>(); static { replacements.put("acceptCount", "backlog"); replacements.put("connectionLinger", "soLinger"); replacements.put("connectionTimeout", "soTimeout"); replacements.put("rootFile", "rootfile"); } } ProtocolHandler的核心变量如下: ProtocolHandler的内部包含AbstractEndpoint<S> endpoint负责监听连接。 public abstract class AbstractProtocol<S> 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<S> endpoint; private Handler<S> handler; private final Set<Processor> waitingProcessors = Collections.newSetFromMap(new ConcurrentHashMap<Processor, Boolean>()); private AsyncTimeout asyncTimeout = null; }