您好,登錄后才能下訂單哦!
本篇內容介紹了“Tomcat是怎么處理Http請求的”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Servlet技術是我們java后端工程師必須掌握的,這里我們可以把java web技術路線可以大致歸納為如下過程:
因為tomcat實現了Servlet規范,所以我們得掌握什么是Servlet?什么是Servlet規范?
什么是Servlet呢?
Servlet是JavaEE規范的一種,主要是為了擴展Java作為Web服務的功能,統一接口。由其他內部廠商如tomcat,jetty內部實現web的功能。如一個http請求到來:容器將請求封裝為servlet中的HttpServletRequest對象,調用init(),service()等方法輸出response,由容器包裝為httpresponse返回給客戶端的過程。
什么是Servlet規范?
從 Jar 包上來說,Servlet 規范就是兩個 Jar 文件。servlet-api.jar 和 jsp-api.jar,Jsp 也是一種 Servlet。
從package上來說,就是 javax.servlet 和 javax.servlet.http 兩個包。
從接口來說,就是規范了 Servlet 接口、Filter 接口、Listener 接口、ServletRequest 接口、ServletResponse 接口等。類圖如下:
為什么我們將tomcat稱為Web容器或者Servlet容器 ?
我們用一張圖來表示他們之間的關系:
簡單的理解:啟動一個ServerSocket,監聽8080端口。Servlet容器用來裝我們開發的Servlet。
tomcat架構介紹
tomcat架構圖
架構圖與tomcat中conf下面的server.xml中內容對比:
<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context docBase="F:/workspace/my-web-maven/target" path="/" reloadable="true" /> <Context docBase="F:/workspace/my-web-maven/target" path="/tian" reloadable="true" /> </Host> </Engine> </Service> </Server>
架構圖和server.xml內容對比,server.xml就是架構圖的xml版本,由此可以猜測我們java代碼中也應該有與之對應的類。
比如說:Listener類、Service類、Host類、Engine類等,這個后面再具體分析,這里只是猜測一下我們java代碼中的實現。
看過前面Mybatis源碼分析文章的同學,這里也應該能猜到,這個server.xml配置文件解析方式以及如何存放這些配置信息。
tomcat啟動時是通過讀取server.xml配置文件的參數,加載每個對應的組件,同時該文件中配置了tomcat的相關可調控參數,實際項目中對tomcat的優化工作大部分都是這個配置文件里的參數調整。
tomcat組件介紹
server
關于server和tomcat的關系,可以理解為我們說的啟動一個tomcat就是啟動一個server。
作為Tomcat最外層的核心組件,Server組件的作用主要有以下幾個。
提供了監聽器機制,用于在Tomcat整個生命周期中對不同事件進行處理;
提供了Tomcat容器全局的命名資源實現;
監聽某個端口以接收SHUTDOWN命令;
service
Service 表示一個或多個 Connector 的集合,這些 Connector 共享同一個 Container 來處理其請求。在同一個 Tomcat 實例內可以包含任意多個 Service 實例,它們彼此獨立
ConnectorConnector用于接受請求并將請求封裝成Request和Response,然后交給Container進行處理,Container處理完之后在交給Connector返回給客戶端。
Container
Container用于封裝和管理Servlet,以及具體處理Request請求;包含4大請求處理組件:引擎(engine)、虛擬主機、上下文(context)組件。Container是容器的父接口,用于封裝和管理Servlet,以及具體處理Request請求,該容器的設計用的是典型的責任鏈的設計模式,它由四個自容器組件構成,分別是Engine、Host、Context、Wrapper。這四個組件是負責關系,存在包含關系。只包含一個引擎。
Engine
表示整個 Servlet 引擎。在 Tomcat 中, Engine 為最高層級的容器對象。盡管 Engine 不是直接處理請求的容器,卻是獲取目標容器的入口。引擎表示可運行的Catalina的servlet引擎實例,并且包含了servlet容器的核心功能。在一個服務中只能有一個引擎。同時,作為一個真正的容器,Engine元素之下可以包含一個或多個虛擬主機Host。
Host
代表一個站點,也可以叫虛擬主機,通過配置Host就可以添加站點。Host容器是Engine容器的子容器,上面也說到Host是受Engine容器管理的,就是指一個虛擬主機,比如我們在訪問具體jsp頁面URL中localhost就是一個虛擬主機,其作用是運行多個應用,并對這些應用進行管理,其子容器是Context,而且一個主機還保存了主機的相關信息。
Context
Context 作為一類容器,用于表示 Servletcontext ,在 Servlet 規范中,一個 Servletcontext 即表示一個獨立的 Web 應用。代表一個應用程序,對應著平時研發的一套程序,或者WEB-INF目錄以及下面的web.xml文件 。
WapperWapper 作為一類容器,用于表示 Web 應用中定義的 Servlet,每一個Wrapper封裝這一個Servlet。
組件關系
tomcat兩個核心組件
Connector:主要負責處理Socket連接,以及Request與Response的轉化。
Container:包括Engine、Host、Context和Wrapper,主要負責內部的處理以及Servlet的管理
tomcat處理Http請求流程
上面說完了tomcat整體架構,下面我們來說說,假設來我們在瀏覽器上輸入
http://localhost:8080/my-web-mave/index.jsp
在tomcat中是如何處理這個請求流程的:
我們的請求被發送到本機端口8080,被在那里偵聽的Coyote HTTP/1.1 Connector獲得。
Connector把該請求交給它所在的Service的Engine來處理,并等待來自Engine的回應 。
Engine獲得請求localhost/my-web-maven/index.jsp,匹配它所擁有的所有虛擬主機Host ,我們的虛擬主機在server.xml中默認配置的就是localhost。
Engine匹配到name=localhost的Host(即使匹配不到也把請求交給該Host處理,因為該Host被定義為該Engine的默認主機)。
localhost Host獲得請求/my-web-maven/index.jsp,匹配它所擁有的所有Context。
Host匹配到路徑為/my-web-maven的Context(如果匹配不到就把該請求交給路徑名為”"的Context去處理)。
path=”/my-web-maven”的Context獲得請求/index.jsp,在它的mapping table中尋找對應的servlet 。
Context匹配到URL PATTERN為*.jsp的servlet,對應于JspServlet類。
構造HttpServletRequest對象和HttpServletResponse對象,作為參數調用JspServlet的doGet或doPost方法 。
Context把執行完了之后的HttpServletResponse對象返回給Host 。
Host把HttpServletResponse對象返回給Engine 。
Engine把HttpServletResponse對象返回給Connector 。
Connector把HttpServletResponse對象返回給客戶browser 。流程圖:有些模糊。
“Tomcat是怎么處理Http請求的”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。