日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tomcat底层原理

發布時間:2023/12/10 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tomcat底层原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Tomcat啟動時到底對我們的應用程序做了什么?

當我們把一個應用程序的war包放到Tomcat的webapps目錄后,啟動Tomcat,然后就可以通過瀏覽器發送Http請求訪問該war包內的Servlet了。
這個過程包括:
1、啟動Tomcat
2、Tomcat處理Http請求
而啟動Tomcat的目的就是為了處理Http請求。

一個Http請求通常是這樣子的:
http://localhost:8080/app/helloServlet
這個請求包括:

協議:http 主機名:localhost 端口:8080 應用名:app Servlet名:helloServlet

我們通俗點來理解這個Http請求就是:瀏覽器通過Http協議,請求localhost:8080上的myapp應用內的helloServlet。

Tomcat架構俯視圖:

二、那分析這個Http請求有什么用呢?和Tomcat有什么關系?

當然有關系,上面這個Http請求中的localhost:8080其實代表的就是Tomcat。我們一個應用程序想要從外部接收網絡數據,那就要綁定一個端口,這個跟TCP協議有關系,外部請求發送給該端口,就能被對于的程序所接收到。Tomcat也是這樣,所以,Tomcat默認綁定的就是8080。

所以上面這個Http請求首先是被Tomcat接收到,然后去解析這個請求。
解析這個請求包括:

請求所使用的方法,是GET,還是POST,還是其他 所請求的應用與Servlet的名字是什么 請求所攜帶的數據

當Tomcat把從8080端口獲取的請求解析完成后,它就應該根據應用名和Servlet名字去找Servlet實現類了,只有找到Servlet實現類才能真正執行Servlet里面的doGet或doPost方法。

所以,這里又分兩步:

根據請求中的應用名和Servlet名怎么找到對應的Servlet實現類呢 怎么執行Servlet實現類中跟請求對應的方法呢

首先關于第二點,很簡單:可以用***反射***
那么對于第一點該怎么實現呢?
其實也很簡單,要么默認,要么映射。
默認的意思就是,請求中的Servlet名就是類名,這種可行,但是不好用,一個類還有包名的,萬一在一個應用中,存在不同的包下存在名字相同的Servlet,這個時候就尷尬了。
所以最好的方式就是映射,一個Servlet名對應一個Servlet實現類。這也就是為什么我們在定義Servlet時,一定要做一個mapping關系,不管是通過@WebServlet注解還是在web.xml中,都需要配置一個mapping才能被訪問到。

所以,Tomcat通過監聽端口,獲取數據,然后解析數據,根據請求url找到對應的Servlet實現類,然后通過反射執行Servlet實現類中的方法

這個流程并不難,如果我們自己實現,30分鐘內可能就能實現出來這么一個功能,這也是Tomcat的主線功能,那么Tomcat復雜在哪呢?
其實還是復雜在這條主線,這條主線再拆分一下就是兩步:

獲取并解析數據 尋找并執行Servlet

tomcat容器對比:

三、Servlet

我們在來細想一下這里的第二步:尋找并執行Servlet

我們通常說Tomcat是一個Servlet容器,到底體現在哪,怎么體現的呢?
我們得先來理解一下Servlet,Servlet=Server+Applet,表達的意思就是運行在服務端的應用程序,它跟運行在客戶端的應用程序是相對的,運行在客戶端的應用程序,可以隨著用戶的操作而發生變化,而運行在服務端的應用程序,用戶是不能直接操作的,你只能通過發送網絡請求來操作它,這就是Servlet的由來。這也就是為什么Servlet規范里會定義ServletRequest,ServletResponse接口,都是跟請求相關的,所以,Servlet其實就為Java程序員方便處理請求和響應的一種抽象,作為Java程序員,你只需要通過定義Servlet,然后接收到的ServletRequest對象就代表請求,而不用關心ServletRequest具體的實現類是什么,是誰實現的,都不用關系,只要知道這個對象代表一個請求即可。
所以誰來實現這些接口呢?大家自然就能想到了,是Tomcat、Jetty這些了。比如Tomcat中對應的請求實現類是RequestFacade,我們在Servlet中進行強制轉化是沒有問題的,比如這么寫:

@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {RequestFacade requestFacade = (RequestFacade) req;resp.getWriter().println("luban annotation servlet");}

我們重新理解了Servlet之后,就可以再來理解Tomcat了,Tomcat確實是一個容器,但是是一個分層的容器。因為一個Servlet代表一個功能,一個應用中可以有多個Servlet,所以在Tomcat中存在Context容器,Context容器中收納Servlet,Context就代表應用,也就是應用上下文,然后我們的應用是部署在主機上的,所以Tomcat中存在Host容器,一個Host容器中可以容納多個Context容器,再繼續,我們可能是多個主機所提供的功能屬于同一范疇的,所以在Tomcat中,在Host之上還有一層Engine。所以我們說的容器包括:Engine、Host、Context。

而Tomcat除開實現了這個層級結構之外,還提供了一些輔助功能。
既然現在容器分層了,所以一個請求在尋找Servlet的過程中,就會經過每一層容器,那么每層容器在這個過程中都可以去做一些事情,并且允許用戶自定義這些事情,比如可以在Host層去指定:所有請求該Host的請求都將日志打印到hostname.log文件中,或者所有請求該Host的請求都由該Host添加一下參數,其他容器也類似,這其實就是一種責任鏈模式,Tomcat中實現了這種模式,是通過:Pipeline和Valve實現的。

好,這是關于容器的分析。
接下來我們再來分析一下Tomcat是怎么解析請求的,上文我們分析了,Tomcat實際上就是把接收到的請求轉化成RequestFacade對象,最后把這個對象傳遞給Servlet。
那么Tomcat的數據從哪來的呢?上文中我們一直默認Tomcat接收的是Http請求,那么這個Http請求是怎么到達Tomcat的呢?總不是憑空飛過來了的吧。
大家應該想到了,是通過網線傳過來的,所以我們要分析Tomcat是怎么接收到Http請求,就要分析網絡傳輸協議了。
首先,我們為什么需要網絡傳輸協議呢?
網絡是用來傳輸數據的,比如現在主機A有一份數據要發送給主機B,那么主機A在擁有數據的同時還是要知道主機B的地址,也就是IP,所以現在相當于主機A上要有:數據+對方IP地址

四、流程圖

Tomcat:

(1)Tomcat中只有一個Server,一個Server可以有多個Service,一個Service可以有多個Connector和一個Container;
(2) Server掌管著整個Tomcat的生死大權;
(4)Service 是對外提供服務的;
(5)Connector用于接受請求并將請求封裝成Request和Response來具體處理;
(6)Container用于封裝和管理Servlet,以及具體處理request請求;

Connector:

四個子容器:

(1)Engine:引擎,用來管理多個站點,一個Service最多只能有一個Engine;
(2)Host:代表一個站點,也可以叫虛擬主機,通過配置Host就可以添加站點;
(3)Context:代表一個應用程序,對應著平時開發的一套程序,或者一個WEB-INF目錄以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封裝著一個Servlet;

上述的包含關系或者說是父子關系,都可以在tomcat的conf目錄下的server.xml配置文件中看出,下圖是刪除了注釋內容之后的一個完整的server.xml配置文件(Tomcat版本為8.0)

更多詳情

五、那么Tcp是用來干什么的呢?

回到上面的場景,主機A想把數據發送給主機B,那誰來保證數據能可靠的到達對方呢?這就是Tcp協議所要做的事情。
那Http協議又是怎么回事呢?我們上面接收的Ip,Tcp都是跟傳輸相關的,而Http是跟應用相關的,是跟數據所表達的意義相關的,比如,主機A發一份數據給主機B之后,主機B接收到這份數據后,它要干什么呢?它要執行什么動作呢?這就是Http協議所要表達的,通過在數據中增加一些有意義的元素,比如請求方法,這樣數據接收方能更快的根據Http協議解析數據,完成對應的動作。
解析的比較粗,因為這不是本文的重點,我的重點是,那么誰來實現Http協議,誰來實現Tcp協議呢?
答案是:操作系統來實現Tcp協議,比如Linux、Windows,運行在操作系統之上的其他應用程序來實現Http協議,比如瀏覽器、Tomcat。
比如Linux的源碼中就有關于Tcp協議的實現,包括三次握手,四次揮手,都是通過c語言來實現的。那么瀏覽器它依照Http協議定義好數據之后,怎么利用Tcp協議發送出去呢?Tomcat怎么利用Tcp協議接收數據呢?
瀏覽器能不能直接調用操作系統中實現TCP協議關于發送數據的函數呢?Tomcat能不能調用對應接收數據的函數呢?
原理上是可以的,但是就像我們開發業務一樣,我們不會將真正實現業務的方法直接暴露給其他人調用,而會提供一個接口,操作系統也一樣,這個接口就是Socket。
所以Tomcat是通過Socket從操作系統獲取數據的,拿到數據后進行解析。
而Tomcat從操作系統系統拿數據又有幾種方式,也就是IO模型:BIO,NIO,AIO,這些不同的模式Tomcat都是支持的,只需要在server.xml中進行配置即可。
簡單記錄了一下關于Tomcat的隨筆,其實關于TSocket、IO模型可以寫得更多一點,限于篇幅,本篇就到此為止吧,下次繼續。

總結

以上是生活随笔為你收集整理的Tomcat底层原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。