Tomcat 啟動完成後,如何將外部 HTTP 請求路由到我們編寫的 Servlet?本文基於源碼梳理完整調用鏈:Http11ConnectionHandler → Http11Processor → CoyoteAdapter → 容器層級聯調用 → StandardWrapperValve → 目標 Servlet。
SocketProcessor 線程,複用/創建 Http11ProcessorCoyoteAdapter.serviceservlet.service()connections 獲取 Processor,無則從 RecycledProcessors(ConcurrentLinkedQueue)取Http11Processor(請求結束後回收到隊列)Http11Processor.process()CoyoteAdapter.service()org.apache.catalina.connector.Request/Response(經 Facade 模式包裝為 Servlet API 類型)postParseRequest:添加 Wrapper-Servlet 映射、解析 SessionIdconnector.getService().getContainer().getPipeline().getFirst().invoke() 進入容器管道request.finishRequest()(回收 Processor)、response.finishResponse()(輸出響應)、recycle() 清理對象StandardEngineValve.invoke()
→ host.getPipeline().getFirst().invoke() // StandardHostValve
StandardHostValve.invoke()
→ context.getPipeline().getFirst().invoke() // StandardContextValve (經 NonLoginAuthenticator)
StandardContextValve.invoke()
→ wrapper.getPipeline().getFirst().invoke() // StandardWrapperValve
ApplicationFilterFactory 創建 Filter 鏈(含默認 WsFilter)filterChain.doFilter() → 依次執行 Filter → 最後調用 servlet.service()
本文梳理了主流程,省略了以下細節:
Coyote Request → Connector Request → RequestFacade理解該流程有助於排查請求不到達 Servlet、Filter 執行順序錯誤、線程池耗盡等疑難問題。