Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

A tutorial on dealing with static Resources in Tomcat

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

preface

Requests in Tomcat are handled by servlets, and static resources are no exception. In the default web.xml, a DefaultServlet is configured to handle static resources, which supports caching and breakpoint continuation.

The basic processing of DefaultServlet is as follows:

Check whether the cache exists for the resource. Check whether the conditions specified in the optional If header field are met. Set the response header field, such as Content-Type, Content-Length, ETag, Last-Modified. Check whether the conditions of Sendfile are met. Otherwise, copy the content to the output stream.

Next, we mainly analyze the design and implementation of resource cache, and the processing of If header field.

1. Design of Resource Cache

Access to disk is much slower than access to memory, so proper caching of some static resources allows the system to respond quickly.

Tomcat in version 6.0.53 to implement static resource processing, with the help of JNDI some API (but when used feel little relationship with JNDI), the relevant class diagram and core methods and attributes are as follows:

Cache related classes:

ResourceCache: cache implementation, providing resource lookup, loading, and destruction functions CacheEntry: a cache entry containing cache name, such as/tomcat.gif, resource and resource attributes, and corresponding directories

The categories associated with the Resource Directory are:

EmptyDirContext: FileDirContext: File system-based resource directory service WARDirContext: war file-based directory service Resource: encapsulates resource content, mainly byte data and input stream ResourceAttributes: resource attributes, mainly content length and last modification time ProxyDirContext: proxy for resource cache and directory service, providing functions such as finding resource cache and verifying whether cache is expired.

By default, the maximum cache size is 10 MB, the maximum individual cache resource size is 512 KB, and the TTL of the cache is 5s.

Generally, when Mapper is mapped to Wrapper that handles static resources, it will cause resource loading. The basic method invocation is as follows:

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)

Cache resources are inserted into the internal array in an orderly manner. The find method is to find the cache by dividing the resource name into two parts. The resource name is the request path. At this time, there are two cases: cache hit and miss.

Cache miss, a new CacheEntry object will be created in cacheLookupmethod, cacheLoad method will be called to add to ResourceCache cache array, and the following operations will be performed on cache entries before adding:

Acquire and initialize cache resource attributes, mainly contentLength and lastModified of the file. If the file length is less than 512KB, load the file contents into memory to mark cache existence and set cache timestamp.

Cache hit, check cache entry:

Check whether it is expired. The current time is greater than the timestamp set by the cache entry. If it is expired, check whether the resource content has been modified. If it has been modified, clear the cache and read the latest content.

The above is the simple process of resource caching.

2. Processing of If header field

The client receives and caches the requested resource. When requesting the resource again, the server verifies whether the resource is modified according to the specific request header field. If there is no change, only a 304 Not Modified response is returned, otherwise, the content of the resource is returned, thus saving bandwidth.

There are two header fields used for resource validation: Last-Modified+If-Modified-Since and ETag+If-None-Match.

Last-Modified+If-Modified-Since, in seconds. This is easy to understand. If the last modification time of the server resource is less than the value of If-Modified-Since, it means that the resource has not changed. If-Modified-Since corresponds to If-Unmodified-Since, which is similar to an assertion that returns only resources with a timestamp less than this, and returns a 412 Precondition Failed error if it is greater than or equal to this timestamp.

There are several drawbacks to using timestamp verification:

The file may only change the modification time, and the content remains unchanged. The file is modified in less than seconds. The server may not be able to accurately obtain the last modification time of the file.

HTTP introduces ETag. ETag(Entity Tags) Unique identifier of the resource, which can be regarded as a Token generated by the server for the resource and used to verify whether the resource is modified. HTTP only specifies that ETag should be placed in double quotes, not what the content is or how to implement it. Tomcat generates ETag logic as "W/\"" + contentLength + "-" + lastModified + "\", where 'W/' indicates case sensitivity.

The value of ETag+If-None-Match, If-None-Match consists of one or more ETags separated by commas. If the ETag of the server resource does not match any of them, it indicates that the requested resource has been modified; otherwise, there is no change. It also has a special value-asterisk (*), which is only used when the resource is uploaded, usually the PUT method, to check whether it has been uploaded.

In addition, If-None-Match has higher priority than If-Modified-Since, that is, If-None-Match does not check the last modified time. The opposite of If-None-Match is an If-Match, which is similar to an assertion that no modification is considered only if the ETag of the resource matches, usually used for breakpoint continuation.

The core code for Tomcat to implement this section is as follows:

//returns true if resources are considered to have changed protected boolean checkIfHeaders(HttpServletRequest request, HttpServletResponse response,ResourceAttributes) throws IOException { return checkIfMatch(request, response, resourceAttributes) && checkIfModifiedSince(request, response, resourceAttributes) && checkIfNoneMatch(request, response, resourceAttributes) && checkIfUnmodifiedSince(request, response, resourceAttributes);}

2.1 one-time request flow

Taking the static resource request/main.css as an example, the header information of the first request response is as follows:

HTTP/1.1 200 OKServer: Apache-Coyote/1.1Accept-Ranges: bytesETag: W/"72259-1557127244000"Last-Modified: Mon, 06 May 2019 07:20:44 GMTContent-Type: text/cssContent-Length: 72259Date: Mon, 06 May 2019 07:20:57 GMT

For the second request, first look at the key information in the request header field:

Cache-Control:max-age=0Connection:keep-aliveHost:localhost:8080If-Modified-Since:Mon, 06 May 2019 07:20:44 GMTIf-None-Match:W/"72259-1557127244000"

After receiving the request, the server will compare the ETag, where the match is successful, indicating that the resource has not been modified, and the response is as follows:

HTTP/1.1 304 Not ModifiedServer: Apache-Coyote/1.1ETag: W/"72259-1557127244000"Date: Mon, 06 May 2019 07:21:46 GMT

Note: When reproducing, use text type, if using Chrome browser, remember to turn on cache.

2.2 Accept-Ranges

In the above response, the server sets an Accept-Ranges: bytes header, literally meaning that a portion of the bytes of the resource can be requested. When the client finds this header, it can try to resume the breakpoint.

The parsing process is the implementation of the HTTP specification, not specifically analyzed here, specification details can be found in RFC7233#section-2.3.

3. Processing of SendFile

Check if SendFile is supported, which is supported in NIO mode, i.e. zero copy, which reduces one copy to application memory and writes data directly to the channel from the kernel. Tomcat tries to send this way when the file size is larger than 48KB.

4. summary

Tomcat's implementation of static resource processing is relatively complete, but it is still slightly inferior to Web servers such as Nginx because they can directly handle static resources, while Tomcat has to do one more mapping. Generally, static and dynamic separation will be performed, allowing Tomcat to focus on handling dynamic requests.

summary

The above is all the content of this article, I hope the content of this article for everyone's study or work has a certain reference learning value, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report