Tomcat study notes 3

Editor: blog Horse Park Jinlong https://www.cnblogs.com/f-ck-need-u/p/7717488.html

tomcat can handle requests for static resources, dynamic resource request can be processed by the servlet. Jsp dynamic resource processing, first by jasper assembly (specifically The JspServlet) to translate into jsp java source code and compiled to run the class. Need to know is that the same static resources is handled by the servlet, servlet except that it uses is to define the default in $ catalina_home / conf / web.xml in the servlet. This paper will analyze tomcat how to handle client requests (concurrent) and how to deal with dynamic and static resources in detail.

1.Tomcat Component Architecture

FIG following two: The above is a diagram of FIG tomcat component system, the following FIG Service component is refined FIG.

among them:

  1. serverManagement component assembly tomcat instance, can monitor a port, remote from the close command to the instance sending the shutdown port.
  2. serviceComponent is one logical component, for binding and Container connector, can be provided with service represents a service outwardly like a general service classes and services daemon. Can be considered a service starts a JVM, strictly speaking, only a engine component corresponding to a JVM (When you define load balancing, jvmRoute definition is used to identify the JVM on the Engine component), but the connector is also working in the JVM.
  3. connectorComponents are listening component, it has four functions:
    • . (1) open listening socket to listen to outside request, and to establish a TCP connection;
    • (2) using the protocol and protocolHandler analysis information request ports, such as http protocol, AJP protocol;
    • (3) based on the analysis of the information request using processer Engine forwards the data to the binding;
    • (4) and receives the response data returned to the client.
  4. containerA container, which is a class of components, is not reflected in the configuration file (e.g., the server.xml) in. It contains four container class components: engine vessel, host vessel, context wrapper, and the container vessel.
  5. engineForwarding from a container for receiving the connector assembly over a request, in accordance with results of the analysis and to pass parameters to match the virtual host. engine is also used to specify the default virtual host.
  6. hostContainer define virtual host, mainly due tomcat as a servlet container, so their root directory specified appBase for each webapp.
  7. contextContainer main path and get some information according to the docBase, the wrapper assembly to which the results of the processes (which provides the operating environment wrapper, so it is called Context context). Generally, with default standard wrapper classes, thus hardly occurs in the context wrapper assembly container.
  8. wrapperContainer processing corresponding to the servlet. It opens servlet life cycle, according to the mapping information given context and parsing web.xml in charge of class loading related objects initialization servlet init (), destroy servlet code execution service () and end of the service servlet objects destory ().
  9. executorEach component Service component provides the thread pool, such a processing request Engine can obtain the thread from the thread pool, thereby achieving tomcat concurrent processing capability. Be sure to note the size of the thread pool Executor is set to Engine components, rather than set for the Connector, the number of threads Connector is set by the acceptorThreadCount property Connector component . If the component to be set in the configuration file, it must be provided at the front Connector assembly Connector assembly for use in executorproperty to reference assembly configured Executor. If not explicitly set, then the default configuration on the Connector component, the default configuration is as follows:
    • (1) .maxThreads: maximum number of threads, the default value of 200.
    • (2) .minSpareThreads: Minimum number of idle threads, the default value of 25.
    • (3) .maxIdleTime: idle thread is idle threads How long will destroy the default value of 60,000 that is one minute.
    • (4) .prestartminSpareThreads: directly create equal to the minimum number of idle threads when the thread whether to start the executor, the default value is false, that is, it will be created only when there is a connection request to enter.

The tomcat component architecture described above, the process generally is very easy to handle requests deduced:

Client(request)-->Connector-->Engine-->Host-->Context-->Wrapper(response data)-->Connector(response header)-->Client

2.Tomcat and httpd / nginx differences in processing requests and listens

On listening and processing requests, tomcat and httpd / nginx services program is not the same, but the difference is huge. Accordingly, when the processing request is understood, must not be httpd / nginx processing mode set in the tomcat.

About httpd / nginx services program processing time of connection, only a brief description here to reflect differences at them and tomcat For details, see my other article: must know the socket and TCP connection process .

(1). Httpd / nginx are all listening process / thread is responsible for monitoring, when listening to a connection request will generate a new one 已连接套接字put in a queue called connected, and then monitor the process / thread to continue to go back to listening. Responsible for handling requests and work processes / threads from the queue acquires 已连接套接字and establishes TCP connection with the client, and then communicate with the client, the client including receiving a resource request data, the response data and to build the client.

(2) .tomcat While listening and processing requests will also work using different components for processing, but the thread monitor connector directly to request the establishment of a TCP connection, and has been working with the client to maintain the connection. connector thread will analyze the request and the results forwarded to the Engine components that are bound, Engine thread is responsible for processing the request and response data to build, but will not establish any connection Engine component and the client. All data sources are Engine Connector, any one client resource request will be sent to the connector, the connector and forwarded to the Engine . After building Engine response, the response again forwards the data to the Connector, by Connector do some processing (e.g., plus header field) to reply to the client.

As long as it can be deduced clearly connected tomcat and request processing: any time request from the outside flows are bound to go through connector, any response time data flowing from the local also will go through Connector . This is the significance of ── connector connects the client and server servlet.

2.1 tomcat how to handle concurrent requests

IO connector assembly protocol supports four types: synchronous blocking BIO, synchronous non-blocking NIO, non-blocking asynchronous NIO2, IO model APR (IO APR model is just one of the functions of the library module) Apache Foundation. The difference is shown below, BIO addition, other models in IO requests are accepted on a new non-blocking, BIO therefore not considered here, but the connector is now no one provided BIO mode.

In the table, the most concern is "Wait for next Request" line, NIO / NIO2 / APR are Non Blocking, this would not be blocked when a request is being processed, may receive additional request, which is to achieve tomcat concurrent key to process the request.

Look at the number of concurrent connector assembly and related setup options:

acceptorThreadCount:用于接收连接请求的线程数。默认值为1。多核CPU系统应该增大该值,另外由于长连接的存在,也应该考虑增大该值。
maxThreads:线程池中最多允许存在多少线程用于处理请求。默认值为200。它是最大并发处理的数量,但不影响接收线程接收更多的连接。
maxConnections:服务端允许接收和处理的最大连接数。当达到该值后,操作系统还能继续接收额外acceptCount个的连接请求,但这些连接暂时不会被处理。当Connector类型为BIO模型时的默认值等于maxThread的值,当为NIO/NIO2模型时的默认值为10000,当APR时默认长度为8192。
acceptCount:当所有请求处理线程都处于忙碌状态时,连接请求将进入等待队列,该值设置等待队列的长度。当达到队列最大值后,如果还有新连接请求进入,则会被拒绝。默认队列长度为100。

从上面几个属性的意义来分析并发机制:

  • (1).connector中最多有acceptorThreadCount个专门负责监听、接收连接请求并建立TCP连接的线程,这些线程是非阻塞的(不考虑BIO)。当和某客户端建立TCP连接后,可以继续去监听或者将Engine返回的数据发送给客户端或者处理其它事情。
  • (2).线程池中的最大线程数maxThreads决定了某一刻允许处理的最大并发请求数,这是专门负责处理connector转发过来的请求的线程,可以认为这些线程专门是为Engine组件服务的(因此我将其称之为Engine线程)。注意,maxThreads决定的是某一刻的最大并发处理能力,但不意味着maxThreads数量的线程只能处理maxThreads数量的请求,因为这些Engine线程也是非阻塞的,当处理某个请求时出现IO等待时,它不会阻塞,而是继续处理其它请求。也就是说,每个请求都占用一个Engine线程直到该客户端的所有请求处理完毕,但每个Engine线程可以处理多个请求。同时还能推测出,每个connector线程可以和多个Engine线程绑定(connector线程的数量远少于Engine线程的数量)。
  • (3).当并发请求数量逐渐增多,tomcat处理能力的极限由maxConnector决定,这个值是由maxThreads和acceptorThreadCount以及非阻塞特性同时决定的。由于非阻塞特性,无论是connector线程还是Engine线程,都能不断接收、处理新请求。它的默认值看上去很大(10000或8192),但分配到每个线程上的数量并不大。假设不考虑监听线程对数量的影响,仅从处理线程上来看,10000个连接分配给200个处理线程,每个处理线程可以轮询处理50个请求。和nginx默认的一个worker线程允许1024个连接相比,已经很少了,当然,因为架构模型不一样,它们没有可比性。
  • (4).当并发请求数量继续增大,tomcat还能继续接收acceptCount个请求,但不会去建立连接,所以也不会去处理。实际上,这些请求不是tomcat接收的,而是操作系统接收的,接收后放入到由Connector创建的队列中,当tomcat有线程可以处理新的请求了再去队列中取出并处理。

再来细分一下tomcat和httpd/nginx的不同点:

  • (1).httpd/nginx的监听者只负责监听和产生已连接套接字,不会和客户端直接建立TCP连接。而tomcat的监听者connector线程不仅会监听,还会直接建立TCP连接,且一直处于ESTABLISHED状态直到close
  • (2).httpd/nginx的工作进程/线程首先从已连接套接字队列中获取已连接套接字,并与客户端建立TCP连接,然后和客户端通信兵处理请求、响应数据。而tomcat的工作线程(Engine线程)只接受来自connector转发过来的请求,处理完毕后还会将响应数据转发回connector线程,由connector将响应数据传输给客户端(和客户端的所有通信数据都必须经过连接器connector来传输)
  • (3).不难推断出,一个Connector线程可以和多个客户端建立TCP连接,也可以和多个Engine线程建立绑定关系,而一个Engine线程可以处理多个请求。如果不理解并发处理机制,这一点很容易被"Connector组件和Engine组件绑定在一起组成Service组件"这句话误导。这句话的意思并不是要求它们1:1对应,就像httpd/nginx也一样,一个监听者可能对应多个工作者。

因此,tomcat处理连接的过程如下图所示,其中我把Engine线程处理请求的过程用"Engine+N"来表示,例如Engine线程1下的Engine1表示该Engine线程处理的某个请求,Engine2表示该线程处理的另一个请求。

3.Tomcat处理jsp动态资源的过程

假设tomcat的配置如下,其中项目名称为"xiaofang"。

1
2
3
4
5
6
7
8
9
10
11
12
13
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> <Engine name="Catalina" defaultHost="localhost"> <Host name="www.xiaofang.com" appBase="webapps/xiaofang" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="" reloadable="true" /> <Context path="/xuexi" docBase="xuexi" reloadable="true" /> </Host> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> </Host> </Engine> 

当客户端访问http://www.xiaofang.com:8080/xuexi/abc.jsp时,其请求的是$CATALINA_HOME/webapps/xiaofang/xuexi/abc.jsp文件。

(1).Connector组件扮演的角色。

Connector组件首先监听到该请求,于是建立TCP连接,并分析该请求。Connector分析请求的内容包括请求的协议、端口、参数等。因为这里没考虑集群问题,因此只可能是http协议而不可能是ajp协议的请求。分析后,将请求和相关参数转发给关联的Engine组件进行处理。

(2).Engine组件扮演的角色。

Engine组件主要用于将请求分配到匹配成功的虚拟主机上,如果没有能匹配成功的,则分配到默认虚拟主机上。对于上面的请求,很显然将分配到虚拟主机www.xiaofang.com上。

(3).Host组件扮演的角色。

Host组件收到Engine传递过来的请求参数后,将对请求中的uri与Context中的path进行匹配,如果和某个Context匹配成功,则将请求交给该Context处理。如果匹配失败,则交给path=""对应的Context来处理。所以,根据匹配结果,上面的请求将交给<Context path="/xuexi" docBase="xuexi" />进行处理。

注意,这次的uri匹配是根据path进行的匹配,它是目录匹配,不是文件匹配。也就是说,只匹配到uri中的xuexi就结束匹配。之所以要明确说明这一点,是因为后面还有一次文件匹配,用于决定交给哪个Servlet来处理。

(4).Context和Wrapper组件扮演的角色。

到了这里,就算真正到了Servlet程序运行的地方了,相比于前面几个组件,这里的过程也更复杂一些。

请求http://www.xiaofang.com:8080/xuexi/abc.jsp经过Host的uri匹配后,分配给<Context path="/xuexi" docBase="xuexi" />进行处理,此时已经匹配了url中的目录,剩下的是abc.jsp。abc.jsp也需要匹配,但这个匹配是根据web.xml中的配置进行匹配的。

首先,从项目名为xiaofang的私有web.xml中进行查找,即webapps/xiaofang/WEB-INF/web.xml。由于此处仅为简单测试,因此并没有该文件。

于是从全局web.xml即$CATALINA_HOME/conf/web.xml中匹配abc.jsp。以下是web.xml中能匹配到该文件名的配置部分。

1
2
3
4
5
6
7
8
9
10
11
<!-- The mappings for the JSP servlet -->
<servlet-mapping>
    <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping> <servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> </servlet>

首先根据<servlet-mapping>中的url-pattern进行文件匹配,发现该url匹配的是servlet-name为"jsp"的servlet,然后再找到与该名称对应的<servlet>标签段,发现处理该动态资源的类为org.apache.jasper.servlet.JspServlet,于是找到该类对应的class文件,该class文件归档在$catalina_home/lib/jasper.jar中。

JspServlet程序的作用是将jsp文件翻译成java源代码文件,并放在$catalina_home/work目录下。然后将该java源文件进行编译,编译后的class文件也放在work目录下。这个class文件就是abc.jsp最终要执行的servlet小程序。

1
2
[root@xuexi ~]# ls /usr/local/tomcat/work/Catalina/www.xiaofang.com/xuexi/org/apache/jsp/
index_jsp.class index_jsp.java new_ 

在翻译后的servlet小程序中,不仅会输出业务逻辑所需的数据,还会输出html/css代码,这样一来,客户端接收到的数据都将是排版好的。

4.Tomcat处理静态资源的过程

对于tomcat来说,无论是动态还是静态资源,都是经过servlet处理的。只不过处理静态资源的servlet是默认的servlet而已。

在$catalina_home/conf/web.xml中关于静态资源处理的配置如下。

1
2
3
4
5
6
7
8
9
10
<!-- The mapping for the default servlet -->
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> </servlet>

需要记住的是,web.xml中的url-pattern是文件匹配,而server.xml中的<Context path="URL-PATTERN" />是目录匹配。

上面web.xml中的<url-pattern>/</url-pattern>表示的是默认servlet。这意味着,当web.xml中没有servlet-mapping能匹配请求url中的路径时,将匹配servlet-name,即名为default的servlet。然后找到处理default的类为org.apache.catalina.servlets.DefaultServlet,该类的class文件归档在$catalina_home/lib/catalina.jar中。该servlet不像JspServlet会翻译jsp文件,它只有最基本的作用:原样输出请求文件中的内容给客户端。

例如,根据前面的配置,下面几个请求都将采用默认servlet进行处理,即当作静态资源处理。

1
2
3
4
http://www.xiaofang.com:8080/xuexi/index.html
http://www.xiaofang.com:8080/xuexi/abc.js http://www.xiaofang.com:8080/xuexi/index http://www.xiaofang.com:8080/xuexi/index.txt 

http://www.xiaofang.com:8080/xuexi则不一定,因为tomcat中默认的index文件包含index.jsp和index.html,而index.jsp排在index.html的前面,只有不存在index.jsp时才请求index.html。

Guess you like

Origin www.cnblogs.com/hrers/p/11482785.html