開篇
?這篇文章主要是將Tomcat的架構(gòu)圖從源碼角度解析了一下庐完,基本上就是把圖和源碼串聯(lián)起來。
Tomcat 總體架構(gòu)
Catalina - 入口
? Catalina對象包含Server對象變量熔萧,在初始化過程中通過Digester注入Server來實現(xiàn)。
- 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實現(xiàn)了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();
// 省略相關(guān)代碼
}
// 省略相關(guān)代碼
// 對比server.xml中<server>標簽的內(nèi)容的port
private int port = 8005;
// 維護Service的對象佛致,
private Service services[] = new Service[0];
private final Object servicesLock = new Object();
// 對比server.xml中<server>標簽的內(nèi)容的shutdown
private String shutdown = "SHUTDOWN";
// 省略相關(guān)代碼
}
Service - StandardService
? StandardService實現(xiàn)了Server接口和Lifecycle接口,核心變量如下:
- Connector connectors[] 變量保存監(jiān)聽的Connector對象辙谜。
- ArrayList<Executor> executors 變量保存多線程對象Executor對象俺榆。
- Engine engine變量保存Service標簽內(nèi)部的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實現(xiàn)了Server接口和Lifecycle接口,核心變量在基類ContainerBase:
- 基類ContainerBase的HashMap<String, Container> children保存<Host>對應(yīng)的對象蜕琴。
- 基類ContainerBase的Realm realm對象保存<Realm>標簽對應(yīng)的對象萍桌。
- 基類ContainerBase的Pipeline pipeline保存調(diào)用鏈并保存Valve對象。
public class StandardEngine extends ContainerBase implements Engine {
public StandardEngine() {
super();
// 省略相關(guān)代碼
}
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實現(xiàn)了Server接口和Lifecycle接口凌简,部分變量在基類ContainerBase:
- appBase 變量保存Host標簽的appBase上炎。
- autoDeploy 變量保存Host標簽的autoDeploy。
- unpackWARs 變量保存Host標簽的unpackWARs雏搂。
- 基類ContainerBase的變量HashMap<String, Container> children保存Context變量藕施。
- 基類ContainerBase的Pipeline pipeline保存調(diào)用鏈并保存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實現(xiàn)了Server接口和Lifecycle接口凸郑,部分變量如下:
- 在context容器中可以定義非常多的屬性裳食,詳細內(nèi)容見官方手冊。
- wrapperClass:實現(xiàn)wrapper容器的類芙沥,wrapper用于管理該context中的servlet胞谈,該類必須實現(xiàn)org.apache.catalina.Wrapper接口尘盼,如果不指定該屬性則采用默認的標準類。
- 基類ContainerBase的Pipeline pipeline保存調(diào)用鏈并保存Valve對象烦绳。
public class StandardContext extends ContainerBase implements Context,
NotificationEmitter {
// 省略相關(guān)代碼
private String wrapperClassName = StandardWrapper.class.getName();
private Class<?> wrapperClass = null;
}
Wrapper - StandardWrapper
?StandardWrapper實現(xiàn)了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實現(xiàn)Lifecycle接口并實現(xiàn)自定義的Executor接口植袍。
- StandardThreadExecutor的executor對象是自定義的ThreadPoolExecutor對象惧眠。
- 自定義的ThreadPoolExecutor對象是在startInternal()方法內(nèi)部初始化,自定義線程工廠以及任務(wù)隊列于个。
- StandardThreadExecutor實現(xiàn)了自定義Executor接口并在execute()方法執(zhí)行自定義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的核心變量如下:
- 協(xié)議處理接口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";
// 協(xié)議處理接口 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的內(nèi)部包含AbstractEndpoint<S> endpoint負責監(jiān)聽連接秀存。
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;
}