Tomcat启动分析(一)-从脚本到main函数分析
当我们在Linux下启动tomcat的时候,通过ps查看其进程信息为,接下来的内容我们就以此进行分析:
- [tomcat@fdd ~]$ ps -ef |grep java
- tomcat : tty1 :: /usr/bin/java -Djava.util.logging.config.file=/home/tomcat/apache-tomcat-7.0./conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize= -Djava.endorsed.dirs=/home/tomcat/apache-tomcat-7.0./endorsed -classpath /home/tomcat/apache-tomcat-7.0./bin/bootstrap.jar:/home/tomcat/apache-tomcat-7.0./bin/tomcat-juli.jar -Dcatalina.base=/home/tomcat/apache-tomcat-7.0. -Dcatalina.home=/home/tomcat/apache-tomcat-7.0. -Djava.io.tmpdir=/home/tomcat/apache-tomcat-7.0./temp org.apache.catalina.startup.Bootstrap start
1 startup.sh分析
我们启动Tomcat的时候,执行的是sh startup.sh,那么在startup.sh中做了哪些事情呢,实际上就是调用catalina.sh,具体过程请看下面分析
- ……
- # 指定Tomcat路径
- PRGDIR=`dirname "$PRG"`
- # 指定调用脚本
- EXECUTABLE=catalina.sh
- ……
- # 执行启动脚本
- exec "$PRGDIR"/"$EXECUTABLE" start "$@"
2. catalina.sh分析
在catalina.sh中完成环境检查、环境初始化、参数初始化、启动操作,也就是在这个里面利用JVM中的java命令执行tomcat的main方法的:
- ……
- # 环境检查
- case $CATALINA_HOME in
- *:*) echo "Using CATALINA_HOME: $CATALINA_HOME";
- echo "Unable to start as CATALINA_HOME contains a colon (:) character";
- exit ;
- esac
- case $CATALINA_BASE in
- *:*) echo "Using CATALINA_BASE: $CATALINA_BASE";
- echo "Unable to start as CATALINA_BASE contains a colon (:) character";
- exit ;
- esac
- ……
- # 初始化环境信息、参数初始化
- if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
- . "$CATALINA_BASE/bin/setenv.sh"
- elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
- . "$CATALINA_HOME/bin/setenv.sh"
- fi
- ……
- # 启动Tomcat,支持
- if [ "$1" = "-security" ] ; then
- if [ $have_tty -eq ]; then
- echo "Using Security Manager"
- fi
- shift
- eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
- -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
- -Djava.security.manager \
- -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
- -Dcatalina.base="\"$CATALINA_BASE\"" \
- -Dcatalina.home="\"$CATALINA_HOME\"" \
- -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
- org.apache.catalina.startup.Bootstrap "$@" start \
- >> "$CATALINA_OUT" >& "&"
- else
- eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
- -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
- -Dcatalina.base="\"$CATALINA_BASE\"" \
- -Dcatalina.home="\"$CATALINA_HOME\"" \
- -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
- org.apache.catalina.startup.Bootstrap "$@" start \
- >> "$CATALINA_OUT" >& "&"
- fi
- ……
3 Bootstrap分析
通过第二章节,我们可以看出实际上调用的是 java org.apache.catalina.startup.Bootstrap这个类,那么我们就来分析一下这个类
3.1 静态代码
类中的静态代码块完成一些参数初始化:
- static {
- // Will always be non-null
- String userDir = System.getProperty("user.dir");
- // Home first
- String home = System.getProperty(Globals.CATALINA_HOME_PROP);
- File homeFile = null;
- if (home != null) {
- File f = new File(home);
- try {
- homeFile = f.getCanonicalFile();
- } catch (IOException ioe) {
- homeFile = f.getAbsoluteFile();
- }
- }
- if (homeFile == null) {
- // First fall-back. See if current directory is a bin directory
- // in a normal Tomcat install
- File bootstrapJar = new File(userDir, "bootstrap.jar");
- if (bootstrapJar.exists()) {
- File f = new File(userDir, "..");
- try {
- homeFile = f.getCanonicalFile();
- } catch (IOException ioe) {
- homeFile = f.getAbsoluteFile();
- }
- }
- }
- if (homeFile == null) {
- // Second fall-back. Use current directory
- File f = new File(userDir);
- try {
- homeFile = f.getCanonicalFile();
- } catch (IOException ioe) {
- homeFile = f.getAbsoluteFile();
- }
- }
- catalinaHomeFile = homeFile;
- System.setProperty(
- Globals.CATALINA_HOME_PROP, catalinaHomeFile.getPath());
- // Then base
- String base = System.getProperty(Globals.CATALINA_BASE_PROP);
- if (base == null) {
- catalinaBaseFile = catalinaHomeFile;
- } else {
- File baseFile = new File(base);
- try {
- baseFile = baseFile.getCanonicalFile();
- } catch (IOException ioe) {
- baseFile = baseFile.getAbsoluteFile();
- }
- catalinaBaseFile = baseFile;
- }
- System.setProperty(
- Globals.CATALINA_BASE_PROP, catalinaBaseFile.getPath());
- }
3.2 调用main方法
main方法是启动一个java程序的入口,任何程序都会有自己的main方法,tomcat是一个WEB容器,也不例外:
- public static void main(String args[]) {
- //如果守护进程为空,则进行初始化
- if (daemon == null) {
- // Don't set daemon until init() has completed
- Bootstrap bootstrap = new Bootstrap();
- try {
- //初始化守护进程,初始化内容参考3.2.1
- bootstrap.init();
- } catch (Throwable t) {
- handleThrowable(t);
- t.printStackTrace();
- return;
- }
- daemon = bootstrap;
- } else {
- // When running as a service the call to stop will be on a new
- // thread so make sure the correct class loader is used to prevent
- // a range of class not found exceptions.
- Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
- }
- try {
- //判断执行命令,并进行相应操作
- String command = "start";
- if (args.length > 0) {
- command = args[args.length - 1];
- }
- if (command.equals("startd")) {
- args[args.length - 1] = "start";
- //加载启动参数,参考3.2.2
- daemon.load(args);
- //启动Tomcat,参考3.2.3
- daemon.start();
- } else if (command.equals("stopd")) {
- args[args.length - 1] = "stop";
- //停止Tomcat守护进程,参考3.2.4
- daemon.stop();
- } else if (command.equals("start")) {
- daemon.setAwait(true);
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stop")) {
- //单独停止Tomcat服务器,参考3.2.5
- 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) {
- // Unwrap the Exception for clearer error reporting
- if (t instanceof InvocationTargetException &&
- t.getCause() != null) {
- t = t.getCause();
- }
- handleThrowable(t);
- t.printStackTrace();
- System.exit(1);
- }
- }
3.2.1 初始化守护进程
此部分完成类加载器初始化
- public void init() throws Exception {
- //初始化类加载器,根据catalina.properties中的加载项进行类加载
- initClassLoaders();
- Thread.currentThread().setContextClassLoader(catalinaLoader);
- SecurityClassLoad.securityClassLoad(catalinaLoader);
- // Load our startup class and call its process() method
- if (log.isDebugEnabled())
- log.debug("Loading startup class");
- Class<?> startupClass =
- catalinaLoader.loadClass
- ("org.apache.catalina.startup.Catalina");
- Object startupInstance = startupClass.newInstance();
- // Set the shared extensions class loader
- if (log.isDebugEnabled())
- log.debug("Setting startup class properties");
- String methodName = "setParentClassLoader";
- Class<?> paramTypes[] = new Class[1];
- paramTypes[0] = Class.forName("java.lang.ClassLoader");
- Object paramValues[] = new Object[1];
- paramValues[0] = sharedLoader;
- Method method =
- startupInstance.getClass().getMethod(methodName, paramTypes);
- method.invoke(startupInstance, paramValues);
- catalinaDaemon = startupInstance;
- }
3.3.2 加载启动参数
在启动脚本中,增加了各种启动参数,此部分就完成这些参数的利用。
- //实际调用org.apache.catalina.startup.Catalina类中的load方法
- private void load(String[] arguments)
- throws Exception {
- // Call the load() method
- String methodName = "load";
- Object param[];
- Class<?> paramTypes[];
- if (arguments==null || arguments.length==0) {
- paramTypes = null;
- param = null;
- } else {
- paramTypes = new Class[1];
- paramTypes[0] = arguments.getClass();
- param = new Object[1];
- param[0] = arguments;
- }
- Method method =
- catalinaDaemon.getClass().getMethod(methodName, paramTypes);
- if (log.isDebugEnabled())
- log.debug("Calling startup class " + method);
- //反射调用
- method.invoke(catalinaDaemon, param);
- }
接下来,我们看具体的load
- //org.apache.catalina.startup.Catalina.load(String[] args)
- public void load(String args[]) {
- try {
- //参数检查
- if (arguments(args)) {
- //加载参数
- load();
- }
- } catch (Exception e) {
- e.printStackTrace(System.out);
- }
- }
- //org.apache.catalina.startup.Catalina.load()
- public void load() {
- long t1 = System.nanoTime();
- //检查临时目录
- initDirs();
- // Before digester - it may be needed
- initNaming();
- // Create and execute our Digester
- // 初始化XML解析器,参考:http://blog.csdn.net/u011545486/article/details/52005412
- Digester digester = createStartDigester();
- InputSource inputSource = null;
- InputStream inputStream = null;
- File file = null;
- try {
- try {
- //获取server.xml配置文件
- file = configFile(); //通过new File()方式读取文件
- inputStream = new FileInputStream(file);
- inputSource = new InputSource(file.toURI().toURL().toString());
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("catalina.configFail", file), e);
- }
- }
- if (inputStream == null) { //读取失败,则通过getResource方式读取文件
- try {
- inputStream = getClass().getClassLoader()
- .getResourceAsStream(getConfigFile());
- inputSource = new InputSource
- (getClass().getClassLoader()
- .getResource(getConfigFile()).toString());
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("catalina.configFail",
- getConfigFile()), e);
- }
- }
- }
- // This should be included in catalina.jar
- // Alternative: don't bother with xml, just create it manually.
- if (inputStream == null) { //如果没有server.xml配置文件,则采用jar包中自带的server-embed.xml
- try {
- inputStream = getClass().getClassLoader()
- .getResourceAsStream("server-embed.xml");
- inputSource = new InputSource
- (getClass().getClassLoader()
- .getResource("server-embed.xml").toString());
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("catalina.configFail",
- "server-embed.xml"), e);
- }
- }
- }
- if (inputStream == null || inputSource == null) { //仍不存在,则进行警告处理,并结束启动
- if (file == null) {
- log.warn(sm.getString("catalina.configFail",
- getConfigFile() + "] or [server-embed.xml]"));
- } else {
- log.warn(sm.getString("catalina.configFail",
- file.getAbsolutePath()));
- if (file.exists() && !file.canRead()) {
- log.warn("Permissions incorrect, read permission is not allowed on the file.");
- }
- }
- return;
- }
- try {
- //解析XML配置
- inputSource.setByteStream(inputStream);
- digester.push(this);
- digester.parse(inputSource);
- } catch (SAXParseException spe) {
- log.warn("Catalina.start using " + getConfigFile() + ": " +
- spe.getMessage());
- return;
- } catch (Exception e) {
- log.warn("Catalina.start using " + getConfigFile() + ": " , e);
- return;
- }
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
- //设置catalina属性
- getServer().setCatalina(this);
- getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
- getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());
- // Stream redirection
- // 设置日志输出流
- initStreams();
- // Start the new server
- try {
- //实际调用的是: org.apache.catalina.util.LifecycleBase.init()
- //启动Tomcat
- getServer().init();
- } catch (LifecycleException e) {
- if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
- throw new java.lang.Error(e);
- } else {
- log.error("Catalina.start", e);
- }
- }
- long t2 = System.nanoTime();
- if(log.isInfoEnabled()) {
- log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
- }
- }
3.2.3 启动Server
完成参数服务初始化之后,就可以进行Server启动。主要包含两部分:Service启动和Server启动。启动过程具体处理在org.apache.catalina.util.LifecycleBase.start()中完成,然后调用org.apache.catalina.core.StandardServer.startInternal()方法进行具体的启动操作
- protected void startInternal() throws LifecycleException {
- fireLifecycleEvent(CONFIGURE_START_EVENT, null);
- setState(LifecycleState.STARTING);
- globalNamingResources.start();
- // Start our defined Services
- synchronized (servicesLock) {
- for (int i = 0; i < services.length; i++) {
- //启动Service
- services[i].start();
- }
- }
- }
3.2.4 停止Tomcat守护进程
此实现过程在org.apache.catalina.startup.Catalina.stop()实现。
- public void stop() {
- try {
- // Remove the ShutdownHook first so that server.stop()
- // doesn't get invoked twice
- if (useShutdownHook) {
- Runtime.getRuntime().removeShutdownHook(shutdownHook);
- // If JULI is being used, re-enable JULI's shutdown to ensure
- // log messages are not lost
- LogManager logManager = LogManager.getLogManager();
- if (logManager instanceof ClassLoaderLogManager) {
- ((ClassLoaderLogManager) logManager).setUseShutdownHook(
- true);
- }
- }
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- // This will fail on JDK 1.2. Ignoring, as Tomcat can run
- // fine without the shutdown hook.
- }
- // Shut down the server
- try {
- //获取服务
- Server s = getServer();
- LifecycleState state = s.getState();
- if (LifecycleState.STOPPING_PREP.compareTo(state) <= 0
- && LifecycleState.DESTROYED.compareTo(state) >= 0) {
- // Nothing to do. stop() was already called
- } else {
- //停止服务
- s.stop();
- s.destroy();
- }
- } catch (LifecycleException e) {
- log.error("Catalina.stop", e);
- }
- }
3.2.5 单独停止Tomcat服务
此实现在org.apache.catalina.startup.Catalina.stopServer(String[] arguments)
- public void stopServer(String[] arguments) {
- if (arguments != null) {
- arguments(arguments);
- }
- //获取Server
- Server s = getServer();
- if (s == null) {
- // Create and execute our Digester
- Digester digester = createStopDigester();
- File file = configFile();
- //如果不存在,则通过配置文件获取Server信息
- try (FileInputStream fis = new FileInputStream(file)) {
- InputSource is =
- new InputSource(file.toURI().toURL().toString());
- is.setByteStream(fis);
- digester.push(this);
- digester.parse(is);
- } catch (Exception e) {
- log.error("Catalina.stop: ", e);
- System.exit(1);
- }
- } else {
- // Server object already present. Must be running as a service
- try {
- //停止服务
- s.stop();
- } catch (LifecycleException e) {
- log.error("Catalina.stop: ", e);
- }
- return;
- }
- // Stop the existing server
- s = getServer();
- if (s.getPort()>0) {
- //通过SOCKET通讯发起停止指令
- try (Socket socket = new Socket(s.getAddress(), s.getPort());
- OutputStream stream = socket.getOutputStream()) {
- String shutdown = s.getShutdown();
- for (int i = 0; i < shutdown.length(); i++) {
- stream.write(shutdown.charAt(i));
- }
- stream.flush();
- } catch (ConnectException ce) {
- log.error(sm.getString("catalina.stopServer.connectException",
- s.getAddress(),
- String.valueOf(s.getPort())));
- log.error("Catalina.stop: ", ce);
- System.exit(1);
- } catch (IOException e) {
- log.error("Catalina.stop: ", e);
- System.exit(1);
- }
- } else {
- log.error(sm.getString("catalina.stopServer"));
- System.exit(1);
- }
- }
通过对比发现,stop()方法与stopServer()方法的区别在于,stop()在执行停止的后,同时进行destroy()操作,而stopServer()并没有发起destory操作。
同时我们可以通过Socket通讯进行关闭Tomcat,在Server.xml中配置了<Server port="8005" shutdown="SHUTDOWN">,那么Tomcat就会开启8005端口,我们可以执行
telnet x.x.x.x 8005
输入: SHUTDOWN
就会发现Tomcat停止了。
那么爱思考的小伙伴就会考虑了,这样岂不是很不安全,如果别人恶意访问我的8005端口,然后发送SHUTDOWN,那我的Tomcat岂不是就给停掉了,这样风险太大了。
放心吧,Tomcat监听的8005端口是监听127.0.0.1的8005端口而不是所有IP的8005端口,除了本机可以访问,其他电脑是不可访问的。
- #查看8005端口
- C:\Users\FDD>netstat -an|findstr
- TCP 127.0.0.1: 0.0.0.0: LISTENING
- #查看8080端口
- C:\Users\FDD>netstat -an|findstr
- TCP 0.0.0.0: 0.0.0.0: LISTENING
- TCP 192.168.0.115: 58.251.100.102: ESTABLISHED
- #通过对比可发现,8005是挂在127.0.0.1的,而8080是挂在0.0.0.(表示本机的所有IP)的
附录:
一、Catalina生命周期
Common interface for component life cycle methods. Catalina components may implement this interface (as well as the appropriate interface(s) for the functionality they support) in order to provide a consistent mechanism to start and stop the component.
The valid state transitions for components that support Lifecycle
are:
- start()
- -----------------------------
- | |
- | init() |
- NEW -»-- INITIALIZING |
- | | | | ------------------«-----------------------
- | | |auto | | |
- | | \|/ start() \|/ \|/ auto auto stop() |
- | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
- | | | | |
- | |destroy()| | |
- | --»-----«-- ------------------------«-------------------------------- ^
- | | | |
- | | \|/ auto auto start() |
- | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
- | \|/ ^ | ^
- | | stop() | | |
- | | -------------------------- | |
- | | | | |
- | | | destroy() destroy() | |
- | | FAILED ----»------ DESTROYING ---«----------------- |
- | | ^ | |
- | | destroy() | |auto |
- | --------»----------------- \|/ |
- | DESTROYED |
- | |
- | stop() |
- ----»-----------------------------»------------------------------
- Any state can transition to FAILED.
- Calling start() while a component is in states STARTING_PREP, STARTING or
- STARTED has no effect.
- Calling start() while a component is in state NEW will cause init() to be
- called immediately after the start() method is entered.
- Calling stop() while a component is in states STOPPING_PREP, STOPPING or
- STOPPED has no effect.
- Calling stop() while a component is in state NEW transitions the component
- to STOPPED. This is typically encountered when a component fails to start and
- does not start all its sub-components. When the component is stopped, it will
- try to stop all sub-components - even those it didn't start.
二、Tomcat 启动日志
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server version: Apache Tomcat/7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server built: Apr 11 2016 07:57:09 UTC
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server number: 7.0.69.0
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: OS Name: Linux
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: OS Version: 2.6.32-642.11.1.el6.x86_64
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Architecture: amd64
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Java Home: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.121.x86_64/jre
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: JVM Version: 1.7.0_121-mockbuild_2016_11_11_19_18-b00
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: JVM Vendor: Oracle Corporation
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: CATALINA_BASE: /home/tomcat/apache-tomcat-7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: CATALINA_HOME: /home/tomcat/apache-tomcat-7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djava.util.logging.config.file=/home/tomcat/apache-tomcat-7.0.69/conf/logging.properties
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djava.endorsed.dirs=/home/tomcat/apache-tomcat-7.0.69/endorsed
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dcatalina.base=/home/tomcat/apache-tomcat-7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dcatalina.home=/home/tomcat/apache-tomcat-7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djava.io.tmpdir=/home/tomcat/apache-tomcat-7.0.69/temp
Jan 26, 2016 11:20:31 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Jan 26, 2016 11:20:31 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Jan 26, 2016 11:20:31 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 8801 ms
至此Catalina服务已经初始化完毕,接下来就是启动Service、Server
Jan 26, 2016 11:20:31 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jan 26, 2016 11:20:31 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.69
Jan 26, 2016 11:20:31 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/host-manager
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deployment of web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/host-manager has finished in 3,197 ms
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/manager
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deployment of web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/manager has finished in 223 ms
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/ROOT
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deployment of web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/ROOT has finished in 103 ms
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/docs
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deployment of web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/docs has finished in 204 ms
Jan 26, 2016 11:20:35 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/examples
Jan 26, 2016 11:20:37 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deployment of web application directory /home/tomcat/apache-tomcat-7.0.69/webapps/examples has finished in 1,425 ms
Jan 26, 2016 11:20:37 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Jan 26, 2016 11:20:37 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Jan 26, 2016 11:20:37 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5455 ms
参考资料:
[1] Tomcat启动过程分析(上)
[2] Tomcat启动过程分析(下)
[3]http://www.cnblogs.com/jiaan-geng/category/741736.html
[4]http://blog.csdn.net/beliefer/article/details/51035923
Tomcat启动分析(一)-从脚本到main函数分析的更多相关文章
- Go Revel - main函数分析
运行revel命令时,首先会编译整个项目,在编译时,会根据`app.conf`配置文件生成两个源码文件`tmp/main.go`.`routes/routes.go`,其中`main.go`是整个项目 ...
- RT-thread main函数分析
RT-thread系统的main函数位于startup.c文件中. /** * This function will startup RT-Thread RTOS. */ void rtthread_ ...
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...
- linux下写tomcat启动,重启的脚本
启动: #bash/bin cd /finance/ LANG="en_US.UTF-8" export LANG /finance/tomcat8-finance/bin/cat ...
- tomcat启动控制台报Exception in thread ''main".......“Could not find the main class:.....Bootstrap”问题
startup.bat文件打开最后end下一行加pause调试,重新启动tomcat,发现配置没问题,但是依然报错,发现是jdk版本问题,jdk1.6无法与tomcat8适配,重新装个1.7版本的jd ...
- 插值和空间分析(二)_变异函数分析(R语言)
方法1.散点图 hscat(log(zinc)~, meuse, (:)*) 方法2.变异函数云图 library(gstat) cld <- variogram(log(zinc) ~ , m ...
- linux中tomcat启动脚本:关闭、发布、重启、测试是否成功
说明 在使用jenkins持续集成时,需要实现自动发布包到tomcat.该脚本实现了在jenkins将包发送到linux服务器上后的自动关闭.发布.启动.测试启动是否成功的过程 思路 该思路以tomc ...
- Tomcat启动过程源码解读
根据Tomcat源码来看一下Tomcat启动过程都做了什么 部分代码为主要流程代码,删去了try-catch以及一些校验逻辑,方便理解主流程 先来一张启动过程时序图,了解一下启动顺序 Tomcat启动 ...
- SequoiaDB 系列之五 :源码分析之main函数
好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...
随机推荐
- 使用PrintWriter完成写操作 ,实现简易记事本工具
package seday07; import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOExce ...
- PHP学习—了解篇2
使用PHP 表单 表单处理: PHP超全局变量:$_GET 和 $ _POST 用于处理表单数据(form-data) < form > 表单标签 action属性:规定表单数据提交U ...
- Android 单选列表对话框 setSingleChoiceItems
private Button button; private final CharSequence[] items = { "北京", "上海", " ...
- ODA: After Apply ODA 12.2.1.2.0 Patch, Unable to Create TableSpace Due to [ORA-15001: diskgroup "DATA" does not exist or is not mounted | ORA-15040: diskgroup is incomplete] (Doc ID 2375553.1)
ODA: After Apply ODA 12.2.1.2.0 Patch, Unable to Create TableSpace Due to [ORA-15001: diskgroup &quo ...
- QPNP 8909 8916 充电相关(1)【转】
最近一直在搞电源管理相关内容,之前是8610的bms,现在8916的bms,发现两者还是有点区别的,8916把对last_ocv_uv的估值算法分装成执行文件,作为服务一直运行. 电源管理方面,应该是 ...
- java8-10-Stream的终止操作
Stream的终止操作 * allMatch 是否匹配所有 * anyMatch 是否匹配一个 * noneMatch 是否没有匹配一个 * findFirst 返回第一个 * count ...
- acwing 902. 最短编辑距离
地址 https://www.acwing.com/problem/content/904/ 给定两个字符串A和B,现在要将A经过若干操作变为B,可进行的操作有: 删除–将字符串A中的某个字符删除. ...
- 微服务SpringCloud项目架构搭建入门
Spring的微服务框架SpringCloud受到众多公司欢迎,给大家带来一篇框架搭建入门.本次采用的版本是Spring Cloud版本为Finchley.RELEASE. 一.SpringCloud ...
- ViewTool Hollong BLE Sniffer Support Linux OS Introduction
ViewTool Hollong BLE Sniffer Support Linux OS Introduction 1. Download Software:http://www.viewtool. ...
- python 动态语言和协议编程
动态语言:不需要去定义变量的类型 协议编程:一个类实现了某个魔法函数,这个类就是什么类型,理解为协议