Tomcat分析(1)结构和启动
来源:互联网 发布:利用淘宝客刷单 编辑:程序博客网 时间:2024/06/15 12:34
1.tomcat顶层结构和启动过程
1.结构
Tomcat顶层容器是Server,代表整个服务器,包含至少一个(或多个)Service.
Service包含至少一个(或多个)Connector 和一个Container.
Connector 负责连接如http连接和https连接,并提供Socket,response,request转换.
Container 封装和管理Servlet及request请求.
Catalina是Tomcat的管理类包含load(含init()),start,stop三个方法.
Catalina调用Server中的start,Server中start的调用包含Service的start,Service的start调用包含Connector 和Container的start.同理stop,load.await方法很重要,此方法直接调用 了Server的await方法,这个方法的作用是进入一个循环,让主线程不会退出。
2.Bootstrap启动
Tomcat的入口是Bootstrap的main,main中通过反射调用Catalina的setAwait(true),load(args)和start().
下面代码都是简写
public static void main(String []args){if(deamon == null)Bootstrap bs = new Bootstrap();bs .init();deamon =bs;String command = "start";if(args.length>0)command = args[args.length-1];try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; } if (command.equals("startd")) { args[args.length - 1] = "start";daemon.load(args); daemon.start(); } else if (command.equals("stopd")) { args[args.length - 1] = "stop"; daemon.stop(); } else if (command.equals("start")) { daemon.setAwait(true); daemon.load(args); daemon.start(); } else if (command.equals("stop")) { daemon.stopServer(args); } else if (command.equals("configtest")) { daemon.load(args);if (null==daemon.getServer()) { System.exit(1); } System.exit(0); } else { log.warn("Bootstrap: command \"" + command + "\" does not exist."); } } catch (Throwable t) { if (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } handleThrowable(t); t.printStackTrace();System.exit(1); }}}
public void start(){if(catalinaDeamon==null) init();Method method = catalinaDeamon.getClass().getMothod("start",(Class [])null);method .invoke(catalinaDeamon,(Object [] )null);}
3.Catalina启动
setAwait(true)判断Server启动后是否进入等待状态,load(args)加载配置文件和start()启动Server.
public void load(){ getServer().init() }public void setAwait(boolean b){ await = b; }public void start(){if(getServer() == null) load();getServer().start();....if(await)await();stop(;)}
4.Server启动
Server中提供addServer(),removeServer()来添加删除.
init(),start()循环调用Service中的init(),start().
Server默认实现org.apache.catalina.core.StandarServer,StandarServer继承LifecycleMBeanBase,
LifecycleMBeanBase又继承LifecycleBase,init()和start()定义在LifecycleBase中,LifecycleBase里的init()和start()调用initInternal()和startInernal().这两个都是模板方法,又子类实现
protected void startInternal() throws LifecycleException { …… synchronized (servicesLock) { for (int i = 0; i < services.length; i++) { services[i].start(); } }}protected void initInternal() throws LifecycleException { …… for (int i = 0; i < services.length; i++) { services[i].init(); }}
StandardServer中还实现了await方法,Catalina中就是调用它让服务器进入等待状态的,其核心代码如下:
public void await() { // 如果端口为-2则不进入循环,直接返回 if( port == -2 ) { return; } // 如果端口为-1则进入循环,而且无法通过网络退出 if( port==-1 ) { try { awaitThread = Thread.currentThread(); while(!stopAwait) { try { Thread.sleep( 10000 ); } catch( InterruptedException ex) { // continue and check the flag } } } finally { awaitThread = null; } return; } // 如果端口不是-1和-2(应该大于0),则会新建一个监听关闭命令的 ServerSocket awaitSocket = new ServerSocket(port, 1,InetAddress.getByName(address)); while (!stopAwait) {ServerSocket serverSocket = awaitSocket; if (serverSocket == null) { break; } Socket socket = null; StringBuilder command = new StringBuilder(); InputStream stream; socket = serverSocket.accept(); socket.setSoTimeout(10 * 1000); stream = socket.getInputStream(); // 检查在指定端口接收到的命令是否和shutdown命令相匹配boolean match = command.toString().equals(shutdown); // 如果匹配则跳出循环 if (match) { break; }}
5.Service启动
Service的默认实现是org.apache.catalina.core.StandardService,StandardService也继承自LifecycleMBeanBase类,所以init和start方法最终也会调用initInternal和startInternal方法。
protected void initInternal() throws LifecycleException { super.initInternal(); if (container != null) { container.init(); } for (Executor executor : findExecutors()) { if (executor instanceof JmxEnabled) { ((JmxEnabled) executor).setDomain(getDomain()); } executor.init(); } mapperListener.init();synchronized (connectorsLock) { for (Connector connector : connectors) { connector.init(); } }}protected void startInternal() throws LifecycleException { setState(LifecycleState.STARTING); if (container != null) { synchronized (container) { container.start(); }} synchronized (executors) { for (Executor executor: executors) { executor.start(); } } mapperListener.start(); synchronized (connectorsLock) { for (Connector connector: connectors) { if (connector.getState() != LifecycleState.FAILED) { connector.start();} } }}
可以看到,StandardService中的initInternal和startInternal方法主要调用container、executors、mapperListener、connectors的init和start方法。mapperListener是Mapper的监听器,可以监听container容器的变化,executors是用在connectors中管理线程的线程池。
serverx.xml配置文件中配置了一个叫tomcatThreadPool的线程池。
- Tomcat分析(1)结构和启动
- Tomcat的启动和目录结构
- Tomcat服务器顶层结构和启动过程
- Tomcat服务器顶层结构和启动过程
- Tomcat启动一闪而过原因分析和问题解决
- Tomcat 6 结构分析
- Tomcat结构分析
- Tomcat 总体结构分析
- tomcat目录结构分析
- Tomcat源码分析(1)--启动流程图
- Tomcat启动分析
- Tomcat启动分析
- Tomcat启动分析
- Tomcat启动分析
- Tomcat的启动分析
- Tomcat启动分析
- Tomcat启动分析
- Tomcat 启动分析
- hdu 6143 Killer Names(容斥原理)
- mysql建表INT类型后面的长度有什么意义(高性能mysql中找到了答案)
- fiddler安装及使用注意事项
- app扩展输出log到文件并从containing app读取
- 安装svn后右键跳出sendrpt not found的解决办法
- Tomcat分析(1)结构和启动
- keyboard
- test
- mac上使用iterm+on my zsh
- 2017网易校招:不要二
- 微软vs stl中vector和list的效率比较
- Android 对EditText进行拦截操作
- Java 基础入门
- C# 以管理员方式启动Winform,进而使用管理员控制Windows Service