• Tomcat启动分析(一)-从脚本到main函数分析


    当我们在Linux下启动tomcat的时候,通过ps查看其进程信息为,接下来的内容我们就以此进行分析:

    [tomcat@fdd ~]$ ps -ef |grep java
    tomcat    1521     1 18 23:20 tty1     00:00:09 /usr/bin/java -Djava.util.logging.config.file=/home/tomcat/apache-tomcat-7.0.69/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/home/tomcat/apache-tomcat-7.0.69/endorsed -classpath /home/tomcat/apache-tomcat-7.0.69/bin/bootstrap.jar:/home/tomcat/apache-tomcat-7.0.69/bin/tomcat-juli.jar -Dcatalina.base=/home/tomcat/apache-tomcat-7.0.69 -Dcatalina.home=/home/tomcat/apache-tomcat-7.0.69 -Djava.io.tmpdir=/home/tomcat/apache-tomcat-7.0.69/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 1;
    esac
    case $CATALINA_BASE in
      *:*) echo "Using CATALINA_BASE:   $CATALINA_BASE";
           echo "Unable to start as CATALINA_BASE contains a colon (:) character";
           exit 1;
    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 1 ]; 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" 2>&1 "&"
    
      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" 2>&1 "&"
    
      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:UsersFDD>netstat -an|findstr 8005
      TCP    127.0.0.1:8005         0.0.0.0:0              LISTENING
    
    #查看8080端口
    C:UsersFDD>netstat -an|findstr 8080
      TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING
      TCP    192.168.0.115:52201    58.251.100.102:8080    ESTABLISHED
    
    #通过对比可发现,8005是挂在127.0.0.1的,而8080是挂在0.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

  • 相关阅读:
    zabbix (2.0.6) 历史记录处乱码
    centos 关闭防火墙
    android 带边框的圆角按钮
    Android开发如何在4.0及以上系统中自定义TitleBar
    Android配置时,点击eclipse里Window->Preferences里的android选项出错
    .net 内存泄露检测工具
    UVA 548 Tree
    UVA 536 Tree Recovery
    UVA 514 Rails
    UVA 442 Matrix Chain Multiplication
  • 原文地址:https://www.cnblogs.com/wlzjdm/p/6964163.html
Copyright © 2020-2023  润新知