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

  1. [tomcat@fdd ~]$ ps -ef |grep java
  2. 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,具体过程请看下面分析

  1. ……
  2. # 指定Tomcat路径
  3. PRGDIR=`dirname "$PRG"`
  4. # 指定调用脚本
  5. EXECUTABLE=catalina.sh
  6. ……
  7. # 执行启动脚本
  8. exec "$PRGDIR"/"$EXECUTABLE" start "$@"

2. catalina.sh分析

在catalina.sh中完成环境检查、环境初始化、参数初始化、启动操作,也就是在这个里面利用JVM中的java命令执行tomcat的main方法的:

  1. ……
  2. # 环境检查
  3. case $CATALINA_HOME in
  4. *:*) echo "Using CATALINA_HOME: $CATALINA_HOME";
  5. echo "Unable to start as CATALINA_HOME contains a colon (:) character";
  6. exit ;
  7. esac
  8. case $CATALINA_BASE in
  9. *:*) echo "Using CATALINA_BASE: $CATALINA_BASE";
  10. echo "Unable to start as CATALINA_BASE contains a colon (:) character";
  11. exit ;
  12. esac
  13. ……
  14. # 初始化环境信息、参数初始化
  15. if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  16. . "$CATALINA_BASE/bin/setenv.sh"
  17. elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  18. . "$CATALINA_HOME/bin/setenv.sh"
  19. fi
  20. ……
  21. # 启动Tomcat,支持
  22. if [ "$1" = "-security" ] ; then
  23. if [ $have_tty -eq ]; then
  24. echo "Using Security Manager"
  25. fi
  26. shift
  27. eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
  28. -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
  29. -Djava.security.manager \
  30. -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
  31. -Dcatalina.base="\"$CATALINA_BASE\"" \
  32. -Dcatalina.home="\"$CATALINA_HOME\"" \
  33. -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  34. org.apache.catalina.startup.Bootstrap "$@" start \
  35. >> "$CATALINA_OUT" >& "&"
  36.  
  37. else
  38. eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
  39. -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
  40. -Dcatalina.base="\"$CATALINA_BASE\"" \
  41. -Dcatalina.home="\"$CATALINA_HOME\"" \
  42. -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  43. org.apache.catalina.startup.Bootstrap "$@" start \
  44. >> "$CATALINA_OUT" >& "&"
  45.  
  46. fi
  47. ……

3 Bootstrap分析

通过第二章节,我们可以看出实际上调用的是 java org.apache.catalina.startup.Bootstrap这个类,那么我们就来分析一下这个类

3.1 静态代码

类中的静态代码块完成一些参数初始化:

  1. static {
  2. // Will always be non-null
  3. String userDir = System.getProperty("user.dir");
  4.  
  5. // Home first
  6. String home = System.getProperty(Globals.CATALINA_HOME_PROP);
  7. File homeFile = null;
  8.  
  9. if (home != null) {
  10. File f = new File(home);
  11. try {
  12. homeFile = f.getCanonicalFile();
  13. } catch (IOException ioe) {
  14. homeFile = f.getAbsoluteFile();
  15. }
  16. }
  17.  
  18. if (homeFile == null) {
  19. // First fall-back. See if current directory is a bin directory
  20. // in a normal Tomcat install
  21. File bootstrapJar = new File(userDir, "bootstrap.jar");
  22.  
  23. if (bootstrapJar.exists()) {
  24. File f = new File(userDir, "..");
  25. try {
  26. homeFile = f.getCanonicalFile();
  27. } catch (IOException ioe) {
  28. homeFile = f.getAbsoluteFile();
  29. }
  30. }
  31. }
  32.  
  33. if (homeFile == null) {
  34. // Second fall-back. Use current directory
  35. File f = new File(userDir);
  36. try {
  37. homeFile = f.getCanonicalFile();
  38. } catch (IOException ioe) {
  39. homeFile = f.getAbsoluteFile();
  40. }
  41. }
  42.  
  43. catalinaHomeFile = homeFile;
  44. System.setProperty(
  45. Globals.CATALINA_HOME_PROP, catalinaHomeFile.getPath());
  46.  
  47. // Then base
  48. String base = System.getProperty(Globals.CATALINA_BASE_PROP);
  49. if (base == null) {
  50. catalinaBaseFile = catalinaHomeFile;
  51. } else {
  52. File baseFile = new File(base);
  53. try {
  54. baseFile = baseFile.getCanonicalFile();
  55. } catch (IOException ioe) {
  56. baseFile = baseFile.getAbsoluteFile();
  57. }
  58. catalinaBaseFile = baseFile;
  59. }
  60. System.setProperty(
  61. Globals.CATALINA_BASE_PROP, catalinaBaseFile.getPath());
  62. }

3.2 调用main方法

main方法是启动一个java程序的入口,任何程序都会有自己的main方法,tomcat是一个WEB容器,也不例外:

  1. public static void main(String args[]) {
  2. //如果守护进程为空,则进行初始化
  3. if (daemon == null) {
  4. // Don't set daemon until init() has completed
  5. Bootstrap bootstrap = new Bootstrap();
  6. try {
  7. //初始化守护进程,初始化内容参考3.2.1
  8. bootstrap.init();
  9. } catch (Throwable t) {
  10. handleThrowable(t);
  11. t.printStackTrace();
  12. return;
  13. }
  14. daemon = bootstrap;
  15. } else {
  16. // When running as a service the call to stop will be on a new
  17. // thread so make sure the correct class loader is used to prevent
  18. // a range of class not found exceptions.
  19. Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
  20. }
  21.  
  22. try {
  23. //判断执行命令,并进行相应操作
  24. String command = "start";
  25. if (args.length > 0) {
  26. command = args[args.length - 1];
  27. }
  28.  
  29. if (command.equals("startd")) {
  30. args[args.length - 1] = "start";
  31. //加载启动参数,参考3.2.2
  32. daemon.load(args);
  33. //启动Tomcat,参考3.2.3
  34. daemon.start();
  35. } else if (command.equals("stopd")) {
  36. args[args.length - 1] = "stop";
  37. //停止Tomcat守护进程,参考3.2.4
  38. daemon.stop();
  39. } else if (command.equals("start")) {
  40. daemon.setAwait(true);
  41. daemon.load(args);
  42. daemon.start();
  43. } else if (command.equals("stop")) {
  44. //单独停止Tomcat服务器,参考3.2.5
  45. daemon.stopServer(args);
  46. } else if (command.equals("configtest")) {
  47. //测试配置
  48. daemon.load(args);
  49. if (null==daemon.getServer()) {
  50. System.exit(1);
  51. }
  52. System.exit(0);
  53. } else {
  54. log.warn("Bootstrap: command \"" + command + "\" does not exist.");
  55. }
  56. } catch (Throwable t) {
  57. // Unwrap the Exception for clearer error reporting
  58. if (t instanceof InvocationTargetException &&
  59. t.getCause() != null) {
  60. t = t.getCause();
  61. }
  62. handleThrowable(t);
  63. t.printStackTrace();
  64. System.exit(1);
  65. }
  66.  
  67. }

3.2.1 初始化守护进程

此部分完成类加载器初始化

  1. public void init() throws Exception {
  2. //初始化类加载器,根据catalina.properties中的加载项进行类加载
  3. initClassLoaders();
  4.  
  5. Thread.currentThread().setContextClassLoader(catalinaLoader);
  6.  
  7. SecurityClassLoad.securityClassLoad(catalinaLoader);
  8.  
  9. // Load our startup class and call its process() method
  10. if (log.isDebugEnabled())
  11. log.debug("Loading startup class");
  12. Class<?> startupClass =
  13. catalinaLoader.loadClass
  14. ("org.apache.catalina.startup.Catalina");
  15. Object startupInstance = startupClass.newInstance();
  16.  
  17. // Set the shared extensions class loader
  18. if (log.isDebugEnabled())
  19. log.debug("Setting startup class properties");
  20. String methodName = "setParentClassLoader";
  21. Class<?> paramTypes[] = new Class[1];
  22. paramTypes[0] = Class.forName("java.lang.ClassLoader");
  23. Object paramValues[] = new Object[1];
  24. paramValues[0] = sharedLoader;
  25. Method method =
  26. startupInstance.getClass().getMethod(methodName, paramTypes);
  27. method.invoke(startupInstance, paramValues);
  28.  
  29. catalinaDaemon = startupInstance;
  30.  
  31. }

3.3.2 加载启动参数

在启动脚本中,增加了各种启动参数,此部分就完成这些参数的利用。

  1. //实际调用org.apache.catalina.startup.Catalina类中的load方法
  2. private void load(String[] arguments)
  3. throws Exception {
  4.  
  5. // Call the load() method
  6. String methodName = "load";
  7. Object param[];
  8. Class<?> paramTypes[];
  9. if (arguments==null || arguments.length==0) {
  10. paramTypes = null;
  11. param = null;
  12. } else {
  13. paramTypes = new Class[1];
  14. paramTypes[0] = arguments.getClass();
  15. param = new Object[1];
  16. param[0] = arguments;
  17. }
  18. Method method =
  19. catalinaDaemon.getClass().getMethod(methodName, paramTypes);
  20. if (log.isDebugEnabled())
  21. log.debug("Calling startup class " + method);
  22. //反射调用
  23. method.invoke(catalinaDaemon, param);
  24.  
  25. }

接下来,我们看具体的load

  1. //org.apache.catalina.startup.Catalina.load(String[] args)
  2. public void load(String args[]) {
  3.  
  4. try {
  5. //参数检查
  6. if (arguments(args)) {
  7. //加载参数
  8. load();
  9. }
  10. } catch (Exception e) {
  11. e.printStackTrace(System.out);
  12. }
  13. }
  14.  
  15. //org.apache.catalina.startup.Catalina.load()
  16. public void load() {
  17.  
  18. long t1 = System.nanoTime();
  19. //检查临时目录
  20. initDirs();
  21.  
  22. // Before digester - it may be needed
  23. initNaming();
  24.  
  25. // Create and execute our Digester
  26. // 初始化XML解析器,参考:http://blog.csdn.net/u011545486/article/details/52005412
  27. Digester digester = createStartDigester();
  28.  
  29. InputSource inputSource = null;
  30. InputStream inputStream = null;
  31. File file = null;
  32. try {
  33. try {
  34. //获取server.xml配置文件
  35. file = configFile(); //通过new File()方式读取文件
  36. inputStream = new FileInputStream(file);
  37. inputSource = new InputSource(file.toURI().toURL().toString());
  38. } catch (Exception e) {
  39. if (log.isDebugEnabled()) {
  40. log.debug(sm.getString("catalina.configFail", file), e);
  41. }
  42. }
  43. if (inputStream == null) { //读取失败,则通过getResource方式读取文件
  44. try {
  45. inputStream = getClass().getClassLoader()
  46. .getResourceAsStream(getConfigFile());
  47. inputSource = new InputSource
  48. (getClass().getClassLoader()
  49. .getResource(getConfigFile()).toString());
  50. } catch (Exception e) {
  51. if (log.isDebugEnabled()) {
  52. log.debug(sm.getString("catalina.configFail",
  53. getConfigFile()), e);
  54. }
  55. }
  56. }
  57.  
  58. // This should be included in catalina.jar
  59. // Alternative: don't bother with xml, just create it manually.
  60. if (inputStream == null) { //如果没有server.xml配置文件,则采用jar包中自带的server-embed.xml
  61. try {
  62. inputStream = getClass().getClassLoader()
  63. .getResourceAsStream("server-embed.xml");
  64. inputSource = new InputSource
  65. (getClass().getClassLoader()
  66. .getResource("server-embed.xml").toString());
  67. } catch (Exception e) {
  68. if (log.isDebugEnabled()) {
  69. log.debug(sm.getString("catalina.configFail",
  70. "server-embed.xml"), e);
  71. }
  72. }
  73. }
  74.  
  75. if (inputStream == null || inputSource == null) { //仍不存在,则进行警告处理,并结束启动
  76. if (file == null) {
  77. log.warn(sm.getString("catalina.configFail",
  78. getConfigFile() + "] or [server-embed.xml]"));
  79. } else {
  80. log.warn(sm.getString("catalina.configFail",
  81. file.getAbsolutePath()));
  82. if (file.exists() && !file.canRead()) {
  83. log.warn("Permissions incorrect, read permission is not allowed on the file.");
  84. }
  85. }
  86. return;
  87. }
  88.  
  89. try {
  90. //解析XML配置
  91. inputSource.setByteStream(inputStream);
  92. digester.push(this);
  93. digester.parse(inputSource);
  94. } catch (SAXParseException spe) {
  95. log.warn("Catalina.start using " + getConfigFile() + ": " +
  96. spe.getMessage());
  97. return;
  98. } catch (Exception e) {
  99. log.warn("Catalina.start using " + getConfigFile() + ": " , e);
  100. return;
  101. }
  102. } finally {
  103. if (inputStream != null) {
  104. try {
  105. inputStream.close();
  106. } catch (IOException e) {
  107. // Ignore
  108. }
  109. }
  110. }
  111. //设置catalina属性
  112. getServer().setCatalina(this);
  113. getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
  114. getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());
  115.  
  116. // Stream redirection
  117. // 设置日志输出流
  118. initStreams();
  119.  
  120. // Start the new server
  121. try {
  122. //实际调用的是: org.apache.catalina.util.LifecycleBase.init()
  123. //启动Tomcat
  124. getServer().init();
  125. } catch (LifecycleException e) {
  126. if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
  127. throw new java.lang.Error(e);
  128. } else {
  129. log.error("Catalina.start", e);
  130. }
  131. }
  132.  
  133. long t2 = System.nanoTime();
  134. if(log.isInfoEnabled()) {
  135. log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
  136. }
  137. }

3.2.3 启动Server

完成参数服务初始化之后,就可以进行Server启动。主要包含两部分:Service启动和Server启动。启动过程具体处理在org.apache.catalina.util.LifecycleBase.start()中完成,然后调用org.apache.catalina.core.StandardServer.startInternal()方法进行具体的启动操作

  1. protected void startInternal() throws LifecycleException {
  2.  
  3. fireLifecycleEvent(CONFIGURE_START_EVENT, null);
  4. setState(LifecycleState.STARTING);
  5.  
  6. globalNamingResources.start();
  7.  
  8. // Start our defined Services
  9. synchronized (servicesLock) {
  10. for (int i = 0; i < services.length; i++) {
  11.  
  12. //启动Service
  13. services[i].start();
  14. }
  15. }
  16. }

3.2.4 停止Tomcat守护进程

此实现过程在org.apache.catalina.startup.Catalina.stop()实现。

  1. public void stop() {
  2.  
  3. try {
  4. // Remove the ShutdownHook first so that server.stop()
  5. // doesn't get invoked twice
  6. if (useShutdownHook) {
  7. Runtime.getRuntime().removeShutdownHook(shutdownHook);
  8.  
  9. // If JULI is being used, re-enable JULI's shutdown to ensure
  10. // log messages are not lost
  11. LogManager logManager = LogManager.getLogManager();
  12. if (logManager instanceof ClassLoaderLogManager) {
  13. ((ClassLoaderLogManager) logManager).setUseShutdownHook(
  14. true);
  15. }
  16. }
  17. } catch (Throwable t) {
  18. ExceptionUtils.handleThrowable(t);
  19. // This will fail on JDK 1.2. Ignoring, as Tomcat can run
  20. // fine without the shutdown hook.
  21. }
  22.  
  23. // Shut down the server
  24. try {
  25. //获取服务
  26. Server s = getServer();
  27. LifecycleState state = s.getState();
  28. if (LifecycleState.STOPPING_PREP.compareTo(state) <= 0
  29. && LifecycleState.DESTROYED.compareTo(state) >= 0) {
  30. // Nothing to do. stop() was already called
  31. } else {
  32. //停止服务
  33. s.stop();
  34. s.destroy();
  35. }
  36. } catch (LifecycleException e) {
  37. log.error("Catalina.stop", e);
  38. }
  39.  
  40. }

3.2.5 单独停止Tomcat服务

此实现在org.apache.catalina.startup.Catalina.stopServer(String[] arguments)

  1. public void stopServer(String[] arguments) {
  2.  
  3. if (arguments != null) {
  4. arguments(arguments);
  5. }
  6. //获取Server
  7. Server s = getServer();
  8. if (s == null) {
  9. // Create and execute our Digester
  10. Digester digester = createStopDigester();
  11. File file = configFile();
  12. //如果不存在,则通过配置文件获取Server信息
  13. try (FileInputStream fis = new FileInputStream(file)) {
  14. InputSource is =
  15. new InputSource(file.toURI().toURL().toString());
  16. is.setByteStream(fis);
  17. digester.push(this);
  18. digester.parse(is);
  19. } catch (Exception e) {
  20. log.error("Catalina.stop: ", e);
  21. System.exit(1);
  22. }
  23. } else {
  24. // Server object already present. Must be running as a service
  25. try {
  26. //停止服务
  27. s.stop();
  28. } catch (LifecycleException e) {
  29. log.error("Catalina.stop: ", e);
  30. }
  31. return;
  32. }
  33.  
  34. // Stop the existing server
  35. s = getServer();
  36. if (s.getPort()>0) {
  37. //通过SOCKET通讯发起停止指令
  38. try (Socket socket = new Socket(s.getAddress(), s.getPort());
  39. OutputStream stream = socket.getOutputStream()) {
  40. String shutdown = s.getShutdown();
  41. for (int i = 0; i < shutdown.length(); i++) {
  42. stream.write(shutdown.charAt(i));
  43. }
  44. stream.flush();
  45. } catch (ConnectException ce) {
  46. log.error(sm.getString("catalina.stopServer.connectException",
  47. s.getAddress(),
  48. String.valueOf(s.getPort())));
  49. log.error("Catalina.stop: ", ce);
  50. System.exit(1);
  51. } catch (IOException e) {
  52. log.error("Catalina.stop: ", e);
  53. System.exit(1);
  54. }
  55. } else {
  56. log.error(sm.getString("catalina.stopServer"));
  57. System.exit(1);
  58. }
  59. }

通过对比发现,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端口,除了本机可以访问,其他电脑是不可访问的。

  1. #查看8005端口
  2. C:\Users\FDD>netstat -an|findstr
  3. TCP 127.0.0.1: 0.0.0.0: LISTENING
  4.  
  5. #查看8080端口
  6. C:\Users\FDD>netstat -an|findstr
  7. TCP 0.0.0.0: 0.0.0.0: LISTENING
  8. TCP 192.168.0.115: 58.251.100.102: ESTABLISHED
  9.  
  10. #通过对比可发现,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:

  1. start()
  2. -----------------------------
  3. | |
  4. | init() |
  5. NEW -»-- INITIALIZING |
  6. | | | | ------------------«-----------------------
  7. | | |auto | | |
  8. | | \|/ start() \|/ \|/ auto auto stop() |
  9. | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
  10. | | | | |
  11. | |destroy()| | |
  12. | --»-----«-- ------------------------«-------------------------------- ^
  13. | | | |
  14. | | \|/ auto auto start() |
  15. | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
  16. | \|/ ^ | ^
  17. | | stop() | | |
  18. | | -------------------------- | |
  19. | | | | |
  20. | | | destroy() destroy() | |
  21. | | FAILED ----»------ DESTROYING ---«----------------- |
  22. | | ^ | |
  23. | | destroy() | |auto |
  24. | --------»----------------- \|/ |
  25. | DESTROYED |
  26. | |
  27. | stop() |
  28. ----»-----------------------------»------------------------------
  29.  
  30. Any state can transition to FAILED.
  31.  
  32. Calling start() while a component is in states STARTING_PREP, STARTING or
  33. STARTED has no effect.
  34.  
  35. Calling start() while a component is in state NEW will cause init() to be
  36. called immediately after the start() method is entered.
  37.  
  38. Calling stop() while a component is in states STOPPING_PREP, STOPPING or
  39. STOPPED has no effect.
  40.  
  41. Calling stop() while a component is in state NEW transitions the component
  42. to STOPPED. This is typically encountered when a component fails to start and
  43. does not start all its sub-components. When the component is stopped, it will
  44. 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函数分析的更多相关文章

  1. Go Revel - main函数分析

    运行revel命令时,首先会编译整个项目,在编译时,会根据`app.conf`配置文件生成两个源码文件`tmp/main.go`.`routes/routes.go`,其中`main.go`是整个项目 ...

  2. RT-thread main函数分析

    RT-thread系统的main函数位于startup.c文件中. /** * This function will startup RT-Thread RTOS. */ void rtthread_ ...

  3. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  4. linux下写tomcat启动,重启的脚本

    启动: #bash/bin cd /finance/ LANG="en_US.UTF-8" export LANG /finance/tomcat8-finance/bin/cat ...

  5. tomcat启动控制台报Exception in thread ''main".......“Could not find the main class:.....Bootstrap”问题

    startup.bat文件打开最后end下一行加pause调试,重新启动tomcat,发现配置没问题,但是依然报错,发现是jdk版本问题,jdk1.6无法与tomcat8适配,重新装个1.7版本的jd ...

  6. 插值和空间分析(二)_变异函数分析(R语言)

    方法1.散点图 hscat(log(zinc)~, meuse, (:)*) 方法2.变异函数云图 library(gstat) cld <- variogram(log(zinc) ~ , m ...

  7. linux中tomcat启动脚本:关闭、发布、重启、测试是否成功

    说明 在使用jenkins持续集成时,需要实现自动发布包到tomcat.该脚本实现了在jenkins将包发送到linux服务器上后的自动关闭.发布.启动.测试启动是否成功的过程 思路 该思路以tomc ...

  8. Tomcat启动过程源码解读

    根据Tomcat源码来看一下Tomcat启动过程都做了什么 部分代码为主要流程代码,删去了try-catch以及一些校验逻辑,方便理解主流程 先来一张启动过程时序图,了解一下启动顺序 Tomcat启动 ...

  9. SequoiaDB 系列之五 :源码分析之main函数

    好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...

随机推荐

  1. 使用PrintWriter完成写操作 ,实现简易记事本工具

    package seday07; import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOExce ...

  2. PHP学习—了解篇2

    使用PHP 表单 表单处理: PHP超全局变量:$_GET 和 $ _POST 用于处理表单数据(form-data) < form > 表单标签 ​ action属性:规定表单数据提交U ...

  3. Android 单选列表对话框 setSingleChoiceItems

    private Button button; private final CharSequence[] items = { "北京", "上海", " ...

  4. 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 ...

  5. QPNP 8909 8916 充电相关(1)【转】

    最近一直在搞电源管理相关内容,之前是8610的bms,现在8916的bms,发现两者还是有点区别的,8916把对last_ocv_uv的估值算法分装成执行文件,作为服务一直运行. 电源管理方面,应该是 ...

  6. java8-10-Stream的终止操作

      Stream的终止操作   * allMatch 是否匹配所有 * anyMatch 是否匹配一个 * noneMatch 是否没有匹配一个 * findFirst 返回第一个   * count ...

  7. acwing 902. 最短编辑距离

    地址 https://www.acwing.com/problem/content/904/ 给定两个字符串A和B,现在要将A经过若干操作变为B,可进行的操作有: 删除–将字符串A中的某个字符删除. ...

  8. 微服务SpringCloud项目架构搭建入门

    Spring的微服务框架SpringCloud受到众多公司欢迎,给大家带来一篇框架搭建入门.本次采用的版本是Spring Cloud版本为Finchley.RELEASE. 一.SpringCloud ...

  9. ViewTool Hollong BLE Sniffer Support Linux OS Introduction

    ViewTool Hollong BLE Sniffer Support Linux OS Introduction 1. Download Software:http://www.viewtool. ...

  10. python 动态语言和协议编程

    动态语言:不需要去定义变量的类型 协议编程:一个类实现了某个魔法函数,这个类就是什么类型,理解为协议