第七章-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 的运行状态,诊断性能问题,以及实现自动化运维。


相关资源:

相关推荐
比奥利奥还傲.8 天前
哪吒监控面板实战:部署 Dashboard、接入 Agent、钉钉告警,再配置固定公网访问
网络·人工智能·分布式·1024程序员节
默 语10 天前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
学传打活1 个月前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续3)
微信公众平台·1024程序员节·汉字·昆仑正义文化
学传打活1 个月前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng1681 个月前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心1 个月前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055272 个月前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055272 个月前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝2 个月前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u0103055272 个月前
Java图像处理实战指南
人工智能·1024程序员节