• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法

    使用idea开发工具调试代码的时候,如果是java的web项目,使用的是tomcat作为web容器,打断点debug调试跟踪,当跟踪到org.apache.catalina包下的时候,则无法进入,这是因为idea运行的tomcat是通过插件的方式集成的,tomcat里面的lib包不再项目的依赖路径中,所以不能跟踪进去

    首先在自己项目中被tomcat回调的接口实现类中,标记一个断点信息,通过idea启动web项目,当出现如图所示的断点信息的时候,因为断点位置标记的是tomcat回调的接口类,所以按照调用堆栈网上则是tomcat内部代码,但此时双击org.apache.catalina包下面的类名,是没有任何反应的,因为我们还没有将tomcat对应的依赖文件添加到classpath下面

    添加依赖

    <dependency>
     <groupId>org.apache.tomcat</groupId>
     <artifactId>tomcat-catalina</artifactId>
     <version>8.5.55</version>
     <scope>provided</scope>
    </dependency>

    因为运行时使用的是tomcat的lib目录下面的jar文件,所以此处的scope使用provided方式

    下面就可以进入到tomcat源码调试了

    tomcat启动日志是怎么执行打出来的?

    03-Jun-2020 10:31:30.929 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/8.5.55
    03-Jun-2020 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建:    May 5 2020 22:10:54 UTC
    03-Jun-2020 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号(:   8.5.55.0
    03-Jun-2020 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称:   Windows 10
    03-Jun-2020 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本:      10.0
    03-Jun-2020 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构:       amd64
    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量:   C:\Program Files\Java\jdk1.8.0_212\jre
    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本:  1.8.0_212-b10
    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商:    Oracle Corporation
    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:   C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training
    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:   D:\tomcat8.5.55\apache-tomcat-8.5.55

    通过定位到 VersionLoggerListener 日志可以查看到

    private void log() {
     log.info(sm.getString("versionLoggerListener.serverInfo.server.version",
      ServerInfo.getServerInfo()));
     log.info(sm.getString("versionLoggerListener.serverInfo.server.built",
      ServerInfo.getServerBuilt()));
     log.info(sm.getString("versionLoggerListener.serverInfo.server.number",
      ServerInfo.getServerNumber()));
     log.info(sm.getString("versionLoggerListener.os.name",
      System.getProperty("os.name")));
     log.info(sm.getString("versionLoggerListener.os.version",
      System.getProperty("os.version")));
     log.info(sm.getString("versionLoggerListener.os.arch",
      System.getProperty("os.arch")));
     log.info(sm.getString("versionLoggerListener.java.home",
      System.getProperty("java.home")));
     log.info(sm.getString("versionLoggerListener.vm.version",
      System.getProperty("java.runtime.version")));
     log.info(sm.getString("versionLoggerListener.vm.vendor",
      System.getProperty("java.vm.vendor")));
     log.info(sm.getString("versionLoggerListener.catalina.base",
      System.getProperty("catalina.base")));
     log.info(sm.getString("versionLoggerListener.catalina.home",
      System.getProperty("catalina.home")));
    
    
     if (logArgs) {
     List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
     for (String arg : args) {
      log.info(sm.getString("versionLoggerListener.arg", arg));
     }
     }
    
    
     if (logEnv) {
     SortedMap<String, String> sortedMap = new TreeMap<>(System.getenv());
     for (Map.Entry<String, String> e : sortedMap.entrySet()) {
      log.info(sm.getString("versionLoggerListener.env", e.getKey(), e.getValue()));
     }
     }
    
    
     if (logProps) {
     SortedMap<String, String> sortedMap = new TreeMap<>();
     for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
      sortedMap.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
     }
     for (Map.Entry<String, String> e : sortedMap.entrySet()) {
      log.info(sm.getString("versionLoggerListener.prop", e.getKey(), e.getValue()));
     }
     }
    }

    发现是通过键值对的方式获取的,再通过字符串全局搜索发现

    但是匹配的是英文,那么中文是怎么打出来的呢?

    最后通过调试发现找的是这个

    类似上面的东西,调试的时候发现tocmat的东西启动还是相当多的
    且看下面这个

    idea tomcat启动后的数据

    03-Jun-2020 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.config.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\conf\logging.properties
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52290,suspend=y,server=n
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-javaagent:C:\Users\Administrator\.IntelliJIdea2018.3\system\captureAgent\debugger-agent.jar
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dfile.encoding=UTF-8
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote=
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.port=1099
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.ssl=false
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.password.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.password
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.access.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.access
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.rmi.server.hostname=127.0.0.1
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djdk.tls.ephemeralDHKeySize=2048
    03-Jun-2020 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dignore.endorsed.dirs=
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.base=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.home=D:\tomcat8.5.55\apache-tomcat-8.5.55
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.io.tmpdir=D:\tomcat8.5.55\apache-tomcat-8.5.55\temp

    以上还只是基本的环境配置等启动
    然后是准备链接到tomcat服务

    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 使用APR版本[1.7.0]加载了基于APR的Apache Tomcat本机库[1.2.24]。
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]。
    03-Jun-2020 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true]
    03-Jun-2020 10:31:30.944 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL成功初始化 [OpenSSL 1.1.1g  21 Apr 2020]
    03-Jun-2020 10:31:31.032 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"]
    03-Jun-2020 10:31:31.046 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
    03-Jun-2020 10:31:31.055 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 175489 ms
    03-Jun-2020 10:31:31.080 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina]
    03-Jun-2020 10:31:31.080 信息 [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.55
    03-Jun-2020 10:31:31.089 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"]
    03-Jun-2020 10:31:31.102 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 47 ms

    tomat启动主要是在Catalina中


    然后是

    启动

    /**
    * Await and shutdown.
    */
    public void await() {
    
     getServer().await();
    
    
    }

    其实tomcat启动本质上就是socket的服务器罢了

    @Override
    public void await() {
     // Negative values - don't wait on port - tomcat is embedded or we just don't like ports
     if (port == -2) {
     // undocumented yet - for embedding apps that are around, alive.
     return;
     }
     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;
     }
    
    
     // Set up a server socket to wait on
     try {
     awaitSocket = new ServerSocket(port, 1,
      InetAddress.getByName(address));
     } catch (IOException e) {
     log.error("StandardServer.await: create[" + address
        + ":" + port
        + "]: ", e);
     return;
     }
    
    
     try {
     awaitThread = Thread.currentThread();
    
    
     // Loop waiting for a connection and a valid command
     while (!stopAwait) {
      ServerSocket serverSocket = awaitSocket;
      if (serverSocket == null) {
      break;
      }
    
    
      // Wait for the next connection
      Socket socket = null;
      StringBuilder command = new StringBuilder();
      try {
      InputStream stream;
      long acceptStartTime = System.currentTimeMillis();
      try {
       socket = serverSocket.accept(); //一旦accecpt后面就开始执行了
       socket.setSoTimeout(10 * 1000); // Ten seconds
       stream = socket.getInputStream();
      } catch (SocketTimeoutException ste) {
       // This should never happen but bug 56684 suggests that
       // it does.
       log.warn(sm.getString("standardServer.accept.timeout",
        Long.valueOf(System.currentTimeMillis() - acceptStartTime)), ste);
       continue;
      } catch (AccessControlException ace) {
       log.warn(sm.getString("standardServer.accept.security"), ace);
       continue;
      } catch (IOException e) {
       if (stopAwait) {
       // Wait was aborted with socket.close()
       break;
       }
       log.error(sm.getString("standardServer.accept.error"), e);
       break;
      }
    
    
      // Read a set of characters from the socket
      int expected = 1024; // Cut off to avoid DoS attack
      while (expected < shutdown.length()) {
       if (random == null)
       random = new Random();
       expected += (random.nextInt() % 1024);
      }
      while (expected > 0) {
       int ch = -1;
       try {
       ch = stream.read();
       } catch (IOException e) {
       log.warn(sm.getString("standardServer.accept.readError"), e);
       ch = -1;
       }
       // Control character or EOF (-1) terminates loop
       if (ch < 32 || ch == 127) {
       break;
       }
       command.append((char) ch);
       expected--;
      }
      } finally {
      // Close the socket now that we are done with it
      try {
       if (socket != null) {
       socket.close();
       }
      } catch (IOException e) {
       // Ignore
      }
      }
    
    
      // Match against our command string
      boolean match = command.toString().equals(shutdown);
      if (match) {
      log.info(sm.getString("standardServer.shutdownViaPort"));
      break;
      } else
      log.warn(sm.getString("standardServer.invalidShutdownCommand", command.toString()));
     }
     } finally {
     ServerSocket serverSocket = awaitSocket;
     awaitThread = null;
     awaitSocket = null;
    
    
     // Close the server socket and return
     if (serverSocket != null) {
      try {
      serverSocket.close();
      } catch (IOException e) {
      // Ignore
      }
     }
     }
    }

    tomcat容器启动之后,下面就是Springmvc模块的内容了


    到此这篇关于Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法的文章就介绍到这了,更多相关Idea中tocmat启动源码调试内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    上一篇:Nginx域名转发使用场景代码实例
    下一篇:Docker连接mongodb实现过程及代码案例
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法 Idea,中,tomcat,启动,源码,