美文网首页Tomcat
Tomcat 总体架构-源码组织

Tomcat 总体架构-源码组织

作者: 晴天哥_王志 | 来源:发表于2018-10-14 22:16 被阅读87次

    开篇

     这篇文章主要是将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;
    }
    

    相关文章

      网友评论

        本文标题:Tomcat 总体架构-源码组织

        本文链接:https://www.haomeiwen.com/subject/vqfaaftx.html