Tomcat中對靜態資源的處理教程

2022-09-24 23:54:14 字數 3566 閱讀 3455

前言

tomcat 中的請求都是由 servlet 處理,靜態資源也不例外。在預設的 web.xml 中,配置了乙個 defaultservlet 用於處理靜態資源,它支援快取和斷點續傳。

defaultservlet 的基本處理過程如下:

接下來主要分析資源快取的設計和實現,以及 if 頭域的處理。

1. 資源快取的設計

訪問磁碟的速度遠遠低於訪問記憶體的速度,所以適當的快取一部分靜態資源能夠讓系統快速響應。

tomcat 在 6.0.53 版本實現靜態資源的處理時,借助了 jndi 的一些 api(但在使用時感覺與 jndi 的關係不大),相關類圖及核心方法和屬性如下:

快取相關的類:

資源目錄相關的類是:

預設情況下,快取最大為 10 mb,單個快取資源最大為 512 kb,快取的 ttl 為 5s。

一般的,在 mapper 對映到處理靜態資源的 wrapper 時,會引起資源的載入,基本的方法呼叫情況如下:

mapper.map(messagebytes, messagebytes, mappingdata)

└─mapper.internalmap(charchunk, charchunk, mappingdata)

└─mapper.internalmapwrapper(mapper$context, charchunk, mappingdata)

└─proxydircontext.lookup(string)

└─proxydircontext.cachelookup(string)

└─resourcecache.lookup(string)

└─resourcecache.find(cacheentry, string)

快取資源插入內部陣列時eeydq是有序的,find 方法就是通過資源名二分查詢快取,資源名就是請求路徑,此時有兩種情況,快取命中和未命中。

快取未命中,在 cachelookup 方法中會新建乙個 cacheentry 物件,呼叫 cacheload 方法加入到 resourcecache 的快取陣列中,加入前會對快取條目進行以下操作:

快取命中,會對快取條目進行校驗:

以上就是資源快取簡單的處理過程。

2. if 頭域的處理

客戶端接收並快取請求的資源,,當再次請求此資源時,服務端根據特定的請求頭域來驗證資源是否修改,沒有變動,則只返回乙個 304 not modified 響應,否則返回資源的內容,從而節省頻寬。

用於資源驗證的頭域有兩種,分別是:last-modified+if-modified-since 和 etag+if-none-match。

last-modified+if-modified-since,單位是秒,這個容易理解,如果服務端資源的最後修改時間小於 if-modified-since 的值,表示資源無變動。與 if-modified-since 對應的有個 if-unmodified-since,它類似乙個斷言,小於此時間戳的資源才返回,大於等於的話會返回 412 precondition failed 的錯誤。

使用時間戳校驗有幾個弊端:

因此,http 引入了 etag。etag(entity tags) 資源唯一標識,可看做服務端為資源生成的乙個 token,用於校驗資源是否修改。http 只規定 etag 要放在雙引號內,沒有規定內容是什麼或者要怎麼實現,tomcat 生成 etag 的邏輯是"w/\"" + contentlength + "-" + lastmodified + "\"",其中 'w/' 表示大小寫敏感。

etag+if-none-match,if-none-match 的值由乙個或多個 etag 組成,多個以逗號分割,如果服務端資源的 etag 與其中的任何乙個都不匹配,表示請求的資源有修改;否則無變動。它還有乙個特殊值-星號(*),只在資源上傳程式設計客棧時使用,通常是 put 方法,檢查是否已經上傳過。

此外 if-none-match 的優先順序高於 if-modified-sincewww.cppcns.com,也就是說,存在 if-none-match 就不對最後修改時間進行校驗。與 if-none-match 相對的有個 if-match,它也類似斷言,只有資源的 etag 匹配時才認為沒有修改,通常用於斷點續傳。

tomcat 實現此部分的核心**如下:

// 返回 true 是才認為資源有變動

2.1 一次請求流程

以請求 /main.css 靜態資源為例,第一次請求響應頭資訊如下:

第二次請求時,首先看一下請求頭域關鍵資訊:

cache-control:max-age=0

connection:keep-alive

host:localhost:8080

if-modified-since:mon, 06 may 2019 07:20:44 gmt

if-none-match:w/"72259-1557127244000"

伺服器收到請求後就會比對 etag,這裡匹配成功,表示資源沒有修改,響應如下:

注意:在復現時,要使用文字型別,如果使用 chrome 瀏覽器,記得開啟快取。

2.2 accept-ranges

在上文的響應中,伺服器設定了乙個 accept-ranges: bytes 頭,字面理解就是可以請求資源的一部分位元組,客戶端發現有這個頭時,就可以嘗試斷點續傳。

解析過程就是對 http 規範的實現,這裡不在具體分析了,規範詳細資訊可檢視 rfc7233#secti程式設計客棧on-2.3.

3. sendfile 的處理

檢查是否支援 sendfile,nio 模式下支援此操作,也就是零拷貝,此操作會減少一次到應用記憶體的拷貝,直接從核心將資料寫入通道。tomcat 在檔案大小大於 48kb 時會嘗試使用此方式傳送。

4. 小結

tomcat 對靜態資源處理的實現還是比較完善的,但還是略遜色於 nginx 這類 web 伺服器,因為它們能直接處理靜態資源,而 tomcat 還要多做一次對映。一般的都會進行動靜分離,讓 tomcat 專注處理動態請求。

總結本文標題: tomcat中對靜態資源的處理教程

本文位址:

webpack對靜態資源的處理

一 對的處理 1.首先安裝url loader 因為依賴 file loader 所以要一併安裝,為其指定版本。yarn add url loader 0.6.2 file loader 1.1.6 dev 2.在webpack配置檔案的module中寫入以下內容。的配置 3.在css中引入測試,會...

tomcat配置靜態資源對映

安裝路徑 tomcat conf server.xml prefix localhost access log.suffix txt pattern h l u t r s b debug 與這個 engine 關聯的 logger 記錄的除錯資訊的詳細程度。數字越大,輸出越詳細。如果沒有指定,預設...

Tomcat找不到靜態資源

使用springmvc搭建專案時,我把美工寫好的html轉換成jsp,部署到伺服器上發現找不到資源,我很確定不是路徑寫錯了,絕對路徑和相對路徑都試過了,我在網上找了很多,最常見的是這樣,讓springmvc不處理靜態資源 mvc default servlet handler 但是未能解決我的問題,...