目錄
- 7.1 Spring Boot 內嵌 Tomcat 啓動原理
- 7.2 ServletWebServerApplicationContext 初始化流程
- 7.3 DispatcherServlet 與 Tomcat 協作機制
- 7.4 Tomcat 替換方案對比
- 7.5 自定義 Tomcat 配置
- 7.6 集成最佳實踐
- 7.7 本章小結
7.1 Spring Boot 內嵌 Tomcat 啓動原理
7.1.1 啓動流程概述
整體啓動流程圖
SpringApplication.run
創建ApplicationContext
刷新ApplicationContext
創建ServletWebServerApplicationContext
創建WebServer
創建TomcatEmbeddedServletContainerFactory
創建Tomcat實例
配置Tomcat
啓動Tomcat
註冊DispatcherServlet
應用啓動完成
核心啓動代碼
// 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 創建
// 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 實例創建
// 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 自動配置機制
自動配置類
// 自動配置類
@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();
}
}
}
條件註解
// 條件註解
@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
核心接口
// 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 初始化流程詳解
初始化步驟
// 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);
}
}
自初始化器
// 自初始化器
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 註冊過程
// 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 配置
// 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
詳細處理步驟
// 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 接口
// 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 接口
// 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 依賴配置
<!-- 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 配置
// 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 依賴配置
<!-- 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 配置
// 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%
|
選擇建議
// 選擇建議
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 自定義連接器
自定義連接器配置
// 自定義連接器配置
@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 自定義閥門
自定義閥門實現
// 自定義閥門實現
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);
}
}
註冊自定義閥門
// 註冊自定義閥門
@Configuration
public class ValveConfig {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
// 添加自定義閥門
context.addValve(new CustomValve());
}
};
}
}
7.5.3 自定義過濾器
自定義過濾器實現
// 自定義過濾器實現
@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 自定義監聽器
自定義監聽器實現
// 自定義監聽器實現
@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 配置管理
環境特定配置
# 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
生產環境配置
# 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 參數優化
# JVM 參數優化
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
系統參數優化
# 系統參數優化
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 監控與診斷
健康檢查
// 健康檢查
@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();
}
}
}
性能監控
// 性能監控
@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 本章小結
關鍵要點
- Spring Boot 內嵌 Tomcat 啓動原理:
- 通過 ServletWebServerApplicationContext 創建 Web 服務器
- 使用 TomcatEmbeddedServletContainerFactory 創建 Tomcat 實例
- 自動配置機制簡化了配置過程
- ServletWebServerApplicationContext 初始化流程:
- 創建 Web 服務器
- 註冊 DispatcherServlet
- 配置過濾器和監聽器
- DispatcherServlet 與 Tomcat 協作機制:
- 請求處理流程
- 處理器映射和適配器
- 視圖解析和渲染
- Tomcat 替換方案對比:
- Tomcat:功能完整,性能中等
- Jetty:輕量級,性能較高
- Undertow:高性能,異步處理
- Netty:最高性能,實時應用
- 自定義 Tomcat 配置:
- 自定義連接器配置
- 自定義閥門和過濾器
- 自定義監聽器
- 集成最佳實踐:
- 環境特定配置管理
- 性能優化參數
- 監控與診斷
選擇建議
- 一般應用:使用默認的 Tomcat
- 微服務應用:考慮使用 Jetty
- 高併發應用:考慮使用 Undertow
- 實時應用:考慮使用 Netty
下一步學習
在下一章中,我們將深入探討 Tomcat 的調試與監控,瞭解如何使用各種工具監控 Tomcat 的運行狀態,診斷性能問題,以及實現自動化運維。
相關資源:
- Spring Boot 官方文檔
- Tomcat 集成指南
- Jetty 官方文檔
- Undertow 官方文檔