第七章-Tomcat与SpringBoot集成机制

🧠 第七章:Tomcat 与 Spring Boot 集成机制

目录

  • [7.1 Spring Boot 内嵌 Tomcat 启动原理](#7.1 Spring Boot 内嵌 Tomcat 启动原理)
  • [7.2 ServletWebServerApplicationContext 初始化流程](#7.2 ServletWebServerApplicationContext 初始化流程)
  • [7.3 DispatcherServlet 与 Tomcat 协作机制](#7.3 DispatcherServlet 与 Tomcat 协作机制)
  • [7.4 Tomcat 替换方案对比](#7.4 Tomcat 替换方案对比)
  • [7.5 自定义 Tomcat 配置](#7.5 自定义 Tomcat 配置)
  • [7.6 集成最佳实践](#7.6 集成最佳实践)
  • [7.7 本章小结](#7.7 本章小结)

7.1 Spring Boot 内嵌 Tomcat 启动原理

7.1.1 启动流程概述

整体启动流程图

SpringApplication.run 创建ApplicationContext 刷新ApplicationContext 创建ServletWebServerApplicationContext 创建WebServer 创建TomcatEmbeddedServletContainerFactory 创建Tomcat实例 配置Tomcat 启动Tomcat 注册DispatcherServlet 应用启动完成

核心启动代码
java 复制代码
// Spring Boot 启动入口
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// SpringApplication.run() 方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class<?>[]{primarySource}, args);
}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return new SpringApplication(primarySources).run(args);
}

7.1.2 内嵌 Tomcat 创建过程

TomcatEmbeddedServletContainerFactory 创建
java 复制代码
// TomcatEmbeddedServletContainerFactory 创建
@Configuration
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class EmbeddedServletContainerAutoConfiguration {
    
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory();
    }
}
Tomcat 实例创建
java 复制代码
// Tomcat 实例创建
public class TomcatEmbeddedServletContainerFactory implements ServletWebServerFactory {
    
    @Override
    public WebServer getWebServer(ServletContextInitializer... initializers) {
        // 1. 创建 Tomcat 实例
        Tomcat tomcat = new Tomcat();
        
        // 2. 设置基础目录
        File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        
        // 3. 配置连接器
        Connector connector = new Connector(this.protocol);
        connector.setPort(this.port);
        tomcat.getService().addConnector(connector);
        
        // 4. 配置引擎
        Engine engine = tomcat.getEngine();
        engine.setName("Tomcat");
        engine.setDefaultHost("localhost");
        
        // 5. 配置主机
        Host host = tomcat.getHost();
        host.setName("localhost");
        host.setAppBase(".");
        
        // 6. 添加上下文
        Context context = tomcat.addContext("", ".");
        
        // 7. 配置 Servlet
        configureContext(context, initializers);
        
        // 8. 启动 Tomcat
        tomcat.start();
        
        return new TomcatWebServer(tomcat);
    }
}

7.1.3 自动配置机制

自动配置类
java 复制代码
// 自动配置类
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
         EmbeddedServletContainerCustomizerBeanPostProcessor.class})
public class ServletWebServerFactoryAutoConfiguration {
    
    @Configuration
    @ConditionalOnClass({Servlet.class, Tomcat.class})
    @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
    public static class EmbeddedTomcat {
        
        @Bean
        public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
            return new TomcatEmbeddedServletContainerFactory();
        }
    }
}
条件注解
java 复制代码
// 条件注解
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class EmbeddedTomcat {
    // 只有在类路径中存在 Servlet 和 Tomcat 类时才创建
    // 只有在没有其他 ServletWebServerFactory Bean 时才创建
}

7.2 ServletWebServerApplicationContext 初始化流程

7.2.1 ApplicationContext 层次结构

上下文层次图

ApplicationContext ConfigurableApplicationContext AbstractApplicationContext GenericApplicationContext ServletWebServerApplicationContext 创建WebServer 注册DispatcherServlet

核心接口
java 复制代码
// ApplicationContext 接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    String getId();
    String getApplicationName();
    String getDisplayName();
    long getStartupDate();
    ApplicationContext getParent();
    AutowireCapableBeanFactory getAutowireCapableBeanFactory();
    BeanFactory getParentBeanFactory();
    boolean containsLocalBean(String name);
    boolean containsBeanDefinition(String beanName);
    boolean isSingleton(String name);
    boolean isPrototype(String name);
    boolean isTypeMatch(String name, ResolvableType typeToMatch);
    Class<?> getType(String name);
    String[] getAliases(String name);
}

7.2.2 初始化流程详解

初始化步骤
java 复制代码
// ServletWebServerApplicationContext 初始化
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebApplicationContext {
    
    @Override
    protected void onRefresh() {
        super.onRefresh();
        try {
            // 1. 创建 Web 服务器
            createWebServer();
        } catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }
    
    private void createWebServer() {
        // 1. 获取 ServletWebServerFactory
        ServletWebServerFactory factory = getWebServerFactory();
        
        // 2. 创建 Web 服务器
        this.webServer = factory.getWebServer(getSelfInitializer());
        
        // 3. 启动 Web 服务器
        this.webServer.start();
    }
    
    private ServletWebServerFactory getWebServerFactory() {
        // 1. 从 Bean 工厂获取 ServletWebServerFactory
        String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
        
        if (beanNames.length == 0) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean");
        }
        
        if (beanNames.length > 1) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
        }
        
        return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
    }
}
自初始化器
java 复制代码
// 自初始化器
private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
    return this::selfInitialize;
}

private void selfInitialize(ServletContext servletContext) throws ServletException {
    try {
        // 1. 注册 ServletContext
        registerServletContext(servletContext);
        
        // 2. 注册 DispatcherServlet
        registerDispatcherServlet(servletContext);
        
        // 3. 注册过滤器
        registerFilters(servletContext);
        
        // 4. 注册监听器
        registerListeners(servletContext);
        
    } catch (Exception ex) {
        throw new ServletException("Failed to initialize servlet context", ex);
    }
}

7.2.3 DispatcherServlet 注册

DispatcherServlet 注册过程
java 复制代码
// DispatcherServlet 注册
private void registerDispatcherServlet(ServletContext servletContext) throws ServletException {
    // 1. 创建 DispatcherServlet
    DispatcherServlet dispatcherServlet = new DispatcherServlet(this);
    
    // 2. 配置 DispatcherServlet
    dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
    dispatcherServlet.setContextConfigLocation("");
    
    // 3. 注册 DispatcherServlet
    ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);
    registration.setLoadOnStartup(1);
    registration.addMapping("/");
    
    // 4. 配置初始化参数
    registration.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
    registration.setInitParameter("contextConfigLocation", "");
}
DispatcherServlet 配置
java 复制代码
// DispatcherServlet 配置
public class DispatcherServlet extends FrameworkServlet {
    
    @Override
    protected void onRefresh(ApplicationContext context) {
        // 1. 初始化策略
        initStrategies(context);
    }
    
    protected void initStrategies(ApplicationContext context) {
        // 1. 初始化多部分解析器
        initMultipartResolver(context);
        
        // 2. 初始化区域设置解析器
        initLocaleResolver(context);
        
        // 3. 初始化主题解析器
        initThemeResolver(context);
        
        // 4. 初始化处理器映射器
        initHandlerMappings(context);
        
        // 5. 初始化处理器适配器
        initHandlerAdapters(context);
        
        // 6. 初始化异常解析器
        initHandlerExceptionResolvers(context);
        
        // 7. 初始化视图名称解析器
        initRequestToViewNameTranslator(context);
        
        // 8. 初始化视图解析器
        initViewResolvers(context);
        
        // 9. 初始化 Flash 映射管理器
        initFlashMapManager(context);
    }
}

7.3 DispatcherServlet 与 Tomcat 协作机制

7.3.1 请求处理流程

请求处理流程图

Client Tomcat DispatcherServlet Handler View HTTP Request 解析请求 调用DispatcherServlet 查找HandlerMapping 调用Handler 返回ModelAndView 调用ViewResolver 返回View 返回Response HTTP Response Client Tomcat DispatcherServlet Handler View

详细处理步骤
java 复制代码
// DispatcherServlet 请求处理
public class DispatcherServlet extends FrameworkServlet {
    
    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 1. 设置请求属性
        request.setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.REQUEST);
        request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
        
        // 2. 处理请求
        doDispatch(request, response);
    }
    
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 1. 获取处理器
        HandlerExecutionChain mappedHandler = getHandler(request);
        if (mappedHandler == null) {
            noHandlerFound(request, response);
            return;
        }
        
        // 2. 获取处理器适配器
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        
        // 3. 处理拦截器
        if (!mappedHandler.applyPreHandle(request, response)) {
            return;
        }
        
        // 4. 调用处理器
        ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
        
        // 5. 处理后置拦截器
        mappedHandler.applyPostHandle(request, response, mv);
        
        // 6. 处理视图
        processDispatchResult(request, response, mappedHandler, mv, dispatchException);
    }
}

7.3.2 处理器映射

HandlerMapping 接口
java 复制代码
// HandlerMapping 接口
public interface HandlerMapping {
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

// RequestMappingHandlerMapping 实现
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements MatchableHandlerMapping, EmbeddedValueResolverAware {
    
    @Override
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        // 1. 获取请求路径
        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        
        // 2. 查找处理器方法
        HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
        
        return handlerMethod;
    }
    
    protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
        // 1. 获取所有映射
        List<Match> matches = new ArrayList<>();
        List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
        
        if (directPathMatches != null) {
            addMatchingMappings(directPathMatches, matches, request);
        }
        
        // 2. 选择最佳匹配
        if (matches.isEmpty()) {
            return null;
        }
        
        Match bestMatch = matches.get(0);
        if (matches.size() > 1) {
            Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
            matches.sort(comparator);
            bestMatch = matches.get(0);
        }
        
        return bestMatch.getHandlerMethod();
    }
}

7.3.3 处理器适配器

HandlerAdapter 接口
java 复制代码
// HandlerAdapter 接口
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    long getLastModified(HttpServletRequest request, Object handler);
}

// RequestMappingHandlerAdapter 实现
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean {
    
    @Override
    protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        // 1. 检查请求方法
        checkRequest(request);
        
        // 2. 执行处理器方法
        ModelAndView mav = invokeHandlerMethod(request, response, handlerMethod);
        
        return mav;
    }
    
    protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        // 1. 创建参数解析器
        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        ModelAndViewContainer mavContainer = new ModelAndViewContainer();
        
        // 2. 解析参数
        Object[] args = getMethodArgumentValues(request, mavContainer, handlerMethod);
        
        // 3. 调用处理器方法
        Object returnValue = handlerMethod.invoke(args);
        
        // 4. 处理返回值
        ModelAndView mav = getModelAndView(mavContainer, returnValue);
        
        return mav;
    }
}

7.4 Tomcat 替换方案对比

7.4.1 支持的 Web 服务器

支持的 Web 服务器列表
Web 服务器 依赖 性能 特性 适用场景
Tomcat 默认 中等 功能完整 一般应用
Jetty 需要添加依赖 轻量级 微服务应用
Undertow 需要添加依赖 最高 高性能 高并发应用
Netty 需要添加依赖 最高 异步处理 实时应用

7.4.2 Jetty 集成

Jetty 依赖配置
xml 复制代码
<!-- Jetty 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Jetty 配置
java 复制代码
// Jetty 配置
@Configuration
public class JettyConfig {
    
    @Bean
    public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
        JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
        factory.setPort(8080);
        factory.setContextPath("/");
        return factory;
    }
}

7.4.3 Undertow 集成

Undertow 依赖配置
xml 复制代码
<!-- Undertow 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
Undertow 配置
java 复制代码
// Undertow 配置
@Configuration
public class UndertowConfig {
    
    @Bean
    public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
        UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
        factory.setPort(8080);
        factory.setContextPath("/");
        return factory;
    }
}

7.4.4 性能对比

性能测试结果
Web 服务器 并发连接数 响应时间 吞吐量 内存使用 CPU 使用
Tomcat 10000 50ms 5000 req/s 512MB 60%
Jetty 15000 40ms 6000 req/s 400MB 50%
Undertow 20000 30ms 8000 req/s 300MB 40%
Netty 25000 25ms 10000 req/s 250MB 35%
选择建议
java 复制代码
// 选择建议
public class WebServerSelection {
    
    public ServletWebServerFactory selectWebServer(ApplicationContext context) {
        // 1. 检查配置
        String webServerType = context.getEnvironment().getProperty("server.type", "tomcat");
        
        switch (webServerType.toLowerCase()) {
            case "tomcat":
                return new TomcatEmbeddedServletContainerFactory();
            case "jetty":
                return new JettyEmbeddedServletContainerFactory();
            case "undertow":
                return new UndertowEmbeddedServletContainerFactory();
            default:
                return new TomcatEmbeddedServletContainerFactory();
        }
    }
}

7.5 自定义 Tomcat 配置

7.5.1 自定义连接器

自定义连接器配置
java 复制代码
// 自定义连接器配置
@Configuration
public class TomcatConfig {
    
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                // 自定义上下文配置
                context.addParameter("app.config", "production");
            }
            
            @Override
            protected void customizeConnector(Connector connector) {
                // 自定义连接器配置
                connector.setPort(8080);
                connector.setProtocol("org.apache.coyote.http11.Http11NioProtocol");
                connector.setConnectionTimeout(20000);
                connector.setMaxThreads(200);
                connector.setMinSpareThreads(10);
                connector.setMaxSpareThreads(50);
                connector.setAcceptCount(100);
                connector.setCompression("on");
                connector.setCompressionMinSize(2048);
                connector.setCompressableMimeType("text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json");
                connector.setUseSendfile(true);
            }
        };
    }
}

7.5.2 自定义阀门

自定义阀门实现
java 复制代码
// 自定义阀门实现
public class CustomValve extends ValveBase {
    
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // 1. 记录请求信息
        String requestURI = request.getRequestURI();
        String remoteAddr = request.getRemoteAddr();
        long startTime = System.currentTimeMillis();
        
        // 2. 调用下一个阀门
        getNext().invoke(request, response);
        
        // 3. 记录响应信息
        long endTime = System.currentTimeMillis();
        long responseTime = endTime - startTime;
        
        log.info("Request: {} from {} took {}ms", requestURI, remoteAddr, responseTime);
    }
}
注册自定义阀门
java 复制代码
// 注册自定义阀门
@Configuration
public class ValveConfig {
    
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                // 添加自定义阀门
                context.addValve(new CustomValve());
            }
        };
    }
}

7.5.3 自定义过滤器

自定义过滤器实现
java 复制代码
// 自定义过滤器实现
@Component
public class CustomFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1. 前置处理
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 2. 设置响应头
        httpResponse.setHeader("X-Custom-Header", "Custom Value");
        
        // 3. 调用下一个过滤器
        chain.doFilter(request, response);
        
        // 4. 后置处理
        log.info("Request processed: {}", httpRequest.getRequestURI());
    }
    
    @Override
    public void destroy() {
        // 销毁过滤器
    }
}

7.5.4 自定义监听器

自定义监听器实现
java 复制代码
// 自定义监听器实现
@Component
public class CustomListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 上下文初始化
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("app.startup.time", System.currentTimeMillis());
        
        log.info("Application context initialized");
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 上下文销毁
        log.info("Application context destroyed");
    }
}

7.6 集成最佳实践

7.6.1 配置管理

环境特定配置
yaml 复制代码
# application.yml
server:
  port: 8080
  servlet:
    context-path: /
  tomcat:
    max-threads: 200
    min-spare-threads: 10
    max-spare-threads: 50
    accept-count: 100
    connection-timeout: 20000
    keep-alive-timeout: 60000
    max-keep-alive-requests: 100
    compression:
      enabled: true
      min-response-size: 2048
      mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
    accesslog:
      enabled: true
      pattern: "%h %l %u %t \"%r\" %s %b %D"
      directory: logs
      prefix: access_log
      suffix: .txt
生产环境配置
yaml 复制代码
# application-prod.yml
server:
  port: 8080
  servlet:
    context-path: /
  tomcat:
    max-threads: 500
    min-spare-threads: 50
    max-spare-threads: 100
    accept-count: 200
    connection-timeout: 30000
    keep-alive-timeout: 120000
    max-keep-alive-requests: 200
    compression:
      enabled: true
      min-response-size: 1024
      mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
    accesslog:
      enabled: true
      pattern: "%h %l %u %t \"%r\" %s %b %D"
      directory: /var/log/tomcat
      prefix: access_log
      suffix: .txt

7.6.2 性能优化

JVM 参数优化
bash 复制代码
# JVM 参数优化
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
系统参数优化
bash 复制代码
# 系统参数优化
ulimit -n 65536
echo 'net.core.somaxconn = 65536' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65536' >> /etc/sysctl.conf
sysctl -p

7.6.3 监控与诊断

健康检查
java 复制代码
// 健康检查
@Component
public class TomcatHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        try {
            // 检查 Tomcat 状态
            MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
            ObjectName threadPoolName = new ObjectName("Catalina:type=ThreadPool,name=*");
            Set<ObjectName> threadPools = mBeanServer.queryNames(threadPoolName, null);
            
            if (threadPools.isEmpty()) {
                return Health.down().withDetail("error", "No thread pools found").build();
            }
            
            // 检查线程池状态
            for (ObjectName threadPool : threadPools) {
                int currentThreadCount = (Integer) mBeanServer.getAttribute(threadPool, "currentThreadCount");
                int currentThreadsBusy = (Integer) mBeanServer.getAttribute(threadPool, "currentThreadsBusy");
                int maxThreads = (Integer) mBeanServer.getAttribute(threadPool, "maxThreads");
                
                if (currentThreadsBusy > maxThreads * 0.9) {
                    return Health.down().withDetail("error", "Thread pool is under high load").build();
                }
            }
            
            return Health.up().build();
        } catch (Exception e) {
            return Health.down().withDetail("error", e.getMessage()).build();
        }
    }
}
性能监控
java 复制代码
// 性能监控
@Component
public class TomcatPerformanceMonitor {
    
    private final MeterRegistry meterRegistry;
    
    public TomcatPerformanceMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    @EventListener
    public void handleRequest(RequestHandledEvent event) {
        // 记录请求指标
        Timer.Sample sample = Timer.start(meterRegistry);
        sample.stop(Timer.builder("tomcat.request.duration")
                .tag("method", event.getMethod())
                .tag("status", String.valueOf(event.getStatusCode()))
                .register(meterRegistry));
        
        // 记录请求计数
        Counter.builder("tomcat.request.count")
                .tag("method", event.getMethod())
                .tag("status", String.valueOf(event.getStatusCode()))
                .register(meterRegistry)
                .increment();
    }
}

7.7 本章小结

关键要点

  1. Spring Boot 内嵌 Tomcat 启动原理

    • 通过 ServletWebServerApplicationContext 创建 Web 服务器
    • 使用 TomcatEmbeddedServletContainerFactory 创建 Tomcat 实例
    • 自动配置机制简化了配置过程
  2. ServletWebServerApplicationContext 初始化流程

    • 创建 Web 服务器
    • 注册 DispatcherServlet
    • 配置过滤器和监听器
  3. DispatcherServlet 与 Tomcat 协作机制

    • 请求处理流程
    • 处理器映射和适配器
    • 视图解析和渲染
  4. Tomcat 替换方案对比

    • Tomcat:功能完整,性能中等
    • Jetty:轻量级,性能较高
    • Undertow:高性能,异步处理
    • Netty:最高性能,实时应用
  5. 自定义 Tomcat 配置

    • 自定义连接器配置
    • 自定义阀门和过滤器
    • 自定义监听器
  6. 集成最佳实践

    • 环境特定配置管理
    • 性能优化参数
    • 监控与诊断

选择建议

  1. 一般应用:使用默认的 Tomcat
  2. 微服务应用:考虑使用 Jetty
  3. 高并发应用:考虑使用 Undertow
  4. 实时应用:考虑使用 Netty

下一步学习

在下一章中,我们将深入探讨 Tomcat 的调试与监控,了解如何使用各种工具监控 Tomcat 的运行状态,诊断性能问题,以及实现自动化运维。


相关资源

相关推荐
陈子迩11 小时前
海康威视云台相机的python sdk使用(云台控制)
1024程序员节
Run Freely93711 小时前
Python-UnitTest框架
1024程序员节
zhongvv11 小时前
应广单片机烧录跳线J7专用PCB使用说明
应广单片机·1024程序员节·电路设计·j7跳线·应广单片机烧录
wkj00111 小时前
uv run python main.py和python main.py的区别?
1024程序员节
LoneEon11 小时前
Ubuntu 系统使用 Docker 部署 Jenkins 详细教程
1024程序员节
长欢喜一场11 小时前
高精度算法全解析:从原理到实现
c++·1024程序员节
m0_7482336411 小时前
单调栈详解【C/C++】
c语言·c++·算法·1024程序员节
励志成为糕手11 小时前
Hive数据仓库:架构原理与实践指南
大数据·数据仓库·hive·1024程序员节·hql
Gee Explorer11 小时前
第一篇使用HTML写一个随机点名网页
css·html5·1024程序员节