Tomcat source code analysis!

Source: Internet
Author: User
Tomcat source code analysis (startup Framework)
Preface:
This article is some of my experiences after reading the Tomcat source code. It mainly explains the Tomcat System Framework and startup process. If you have any mistakes, please criticize them!
Suggestion:
After all, the Tomcat framework is still complicated. It is not easy to grasp the Tomcat framework simply by understanding the text. Therefore, you must practice, practice, and practice again. We recommend that you download the Tomcat source code, debug the code, and track the startup process in one step. If you have any questions, refer to this article to see if it is helpful. I believe that the effect and learning speed will be much better!

1. Tomcat's overall framework structure
The basic framework of Tomcat is divided into four layers.
Top level elements:
Server
Service
Connector
HTTP
AJP
Container
Engine
Host
Context
Component
Manager
Logger
Loader
Pipeline
Valve
...
Servers and services are on the top of the framework.
Server: it is actually a backgroud program. The server in Tomcat is used to start and listen to server events (such as restart and close commands. In the standard tomcat configuration file: Server. in XML, we can see "<server port =" 8005 "shutdown =" shutdown "DEBUG =" 0 ">; "shutdown" is the command used by the server to listen to server events)
Service: In tomcat, service refers to a solution to a class of problems. We usually use the service in Tomcat-standalone mode provided by Tomcat by default. In this way, the service not only provides us with parsing JSP and Servlet services, but also provides us with parsing static text services.

Connector: Tomcat handles problems in the container, and where does the container obtain the input information?
Connector is dedicated to this. It encapsulates the data passed from the socket into a request and passes it to the container for processing.
We usually use two types of ctor, called HTTP connectoer, to pass HTTP requests. The other is AJP. When we integrate Apache and tomcat, Apache and tomcat interact through this protocol. (Speaking of the Integration of Apache and tomcat, we usually aim to get apache static resources and let Tomcat parse dynamic JSP or servlet .)
Container: When HTTP connector transfers the requirement to the top-level container: Engin, our line of sight should be moved to the container layer.
At the container layer, we have three types of containers: Engin, host, and context.
Engin: receives the request from the service. After processing, the result is returned to the Service (the service interacts with engin through the media of connector ).
HOST: After engin receives the request passed by the Service, it does not process it by itself, but is handed over to the appropriate host for processing.
Host is the meaning of a virtual host. Generally, we only use one host, that is, "localhost.
Context: After the host receives a request from the host, it will not be processed by itself, but it will be handled by the appropriate context.
For example: <Http: // 127.0.1: 8080/BAR/index. jsp>;
The former is handed over to the context of Foo for processing, and the latter to the context of bar for processing.
Obviously! Context is actually a web app.
We usually do this configuration in server. xml.
<Context Path = "/foo" docbase = "D:/project/Foo/Web"/>;
The context container is used to do what we should do.

Compenent: Next, let's talk about how component works.
First, we need to understand the relationship between containers and components.
The requirement is passed to the container and will be passed to the next container for processing when appropriate.
The container contains a variety of components, which can be understood as providing a variety of value-added services.
MANAGER: when the Manager component is installed in a container, the container supports session management. In fact, session management in Tomcat depends on the Manager component installed in the context.
Logger: After a logger component is installed in a container, what happens in this container is recorded by this component! We usually see catalina_log.time.txt in the logs/directory and localhost.time.txt and localhost_examples_log.time.txt. This is because the logger components are installed in the Engin, host, and context (examples) Containers respectively. This is also the default installation and is also called the standard one :)
Loader: The loader component is usually used only for our context container. loader is used to start the context and manage the classloader of the context.
Pipline: pipeline is such a thing. When a container decides to deliver the requirement passed from the upper-level to the sub-container, it puts the requirement into the container pipeline (pipeline). When the requests flow in the pipeline, they will be intercepted by various valves in the pipeline. For example, two valves are placed in the pipe. The first valve is called "access_allow_vavle". That is to say, when the demand flow is over, it will check which IP address the request belongs to. If this IP address is already in the blacklist, sure, kill! The second valve is called defaul_access_valve, which performs routine checks,
If yes, OK to pass the requirement to the sub-container of the current container. In this way, the requirement is passed in each container, flows, and finally reaches the destination.
Valve: the valve mentioned above.
Tomcat is something like this. We can simply understand the Tomcat framework. It is a top-down structure that contains sub-containers.
2. Tomcat Startup Process
This article describes how to start Tomcat. Since we have a general understanding of the Framework Structure of Tomcat, we can start the parent container first by looking at the start of Tomcat, start the sub-containers one by one. When a container is started, the component installed on it is started. When all components are started and all containers are started, Tomcat itself is started.
Naturally, we can also guess That tomcat startup will be divided into two parts, the first step is assembly. Step 2: start the job.
The Assembly is to install sub-containers for the parent container and install components for each container. In this place we will use digester mode, as for Digester mode what, what is used, how to work. Please refer to After the Assembly is started, once the Assembly is successful, we only need to ignment the top wire, and the entire Tomcat will be activated. This is just like when we want to drive a car that has already been assembled. We just need to insert the key into the key hole, twist it, the engine of the car will start up, and the air conditioner will start up, the safety device will take effect, so that the whole car will be started. (This process is indeed consistent with the Tomcat startup process, so we have to suspect that Tomcat designers are developing Java in GE ).
2.1 interesting names:
Catalina
Tomcat
Bootstrap
Engin
Host
Context
They are very interesting:
Catalina: long-range bomber
Tomcat: pandatv bomber-a type of Bomber (this reminds me of pandatv mobile phones that are proud of Chinese people. Can they be called tomcat in English ??? And reminds me of another advertisement: A fighter in the waveguide-mobile phone and a fighter in the Boeing-aircraft)
Bootstap: boot
Engin: Engine
HOST: host, territory
Context: content, target, and context

... After many years, modern humans have been extinct. The post-modern creature found these words scattered in one piece. A wise guy has translated these things:
Under the guidance of ground service personnel (bootstrap), a Catalina jumped up, far from being a panda bomber (Tomcat! With the excellent engine technology (engin), The pandatv bomber flew over the enemy's territory (host) and targeted the target (context) to cast a nuclear warhead destroying the earth ~ Modern life is like this ~
 
To sum up, it makes us think that GE is also involved in the production of military equipment?
Oppose American imperialism! We are opposed to US hegemony! Long live peace! Long live freedom!

The history of 2.2 is so amazing! Tomcat is started from the org. Apache. Catalina. startup. Bootstrap class!
Two things are done in Bootstrap:
1. Three types of classloader are specified:
Commonloader: Common/classes, common/lib, common/endorsed
Catalinaloader: Server/classes, server/lib, commonloader
Sharedloader: Shared/classes, shared/lib, and commonloader
2. Boot Catalina.
Use reflection technology to call the process method of org. Apache. Catalina. startup. Catalina and pass the parameters in the past.

2.3 Catalina. Java
Catalina has completed several important tasks:
1. Use digester technology to assemble Tomcat containers and components.
1.1 The main content of the assembly work is to install various major components. For example, what kind of servcie is available under the server. The number of contexts that a host can contain. Which components are used by context.
1.2 at the same time, mbeans configuration has been completed in the assembly process. Here, I briefly but not very accurately describe what mbean is and what it uses.
We have created our own objects and managed them by ourselves! But what if we create an object and want others to manage it? I want to at least tell others what we have and how to find it! JMX technology provides us with a means. JMX has three main features. Mbean, agent, connector.
Mbean: used to map our objects. Maybe mbean is the object we created, maybe not, but with it, we can reference our object.
AGENT: You can find mbean.
Connector: Method of connecting to the agent. It can be HTTP, RMI, or socket.
Events that occur during Tomcat Assembly: the initialization of the globalresourceslifecyclelistener class will be triggered:
Protected static registry = mbeanutils. createregistry (); will run
Mbeanutils. createregistry () is based on/org/Apache/Catalina/mbeans-descriptors. create mbeans in the XML configuration file. OK. You can access all components in Tomcat from the outside. (A bit like a backdoor)
2. initialize the top-level server. In fact, it is usually configured to the Service's two ctor. (HTTP, AJP)
3. Start from the server container and ignite the entire tomcat.
4. Create a hook program for the server to check that Tomcat containers are disabled when the server is shut down.
5. Listen to port 8005. If "shutdown" is sent (the default cultivation string), close the 8005 serversocket.
2.4 start various containers
1. Server
Before the server container is started (before_start), start, and after_start events are started, and the corresponding event processor is run.
Start the sub-container of the server: servcie.
2. Service
Sub-container for starting service: engin
Start Connector
3. engin
At the engin level and below, Tomcat uses a consistent startup method.
First, run the specific tasks of each container.
Then, the pre-startup event is triggered.
Immediately, set the label to indicate that the container has been started.
Next, start various components in the container: loader, logger, Manager, etc.
Then, start the mapping component. (Note 1)
Followed by the promoter container.
Next, start the pipeline of the container (pipline)
Then, trigger the startup event
Finally, the post-startup event is triggered.
 
Generally, Engin will do this, host will do the same, and context will do the same. Obviously, we need to use the code reuse technology here. Tomcat uses abstract classes to handle this problem. Containerbase. finally, this part of the code that completes complex functions looks neat and elegant. It is really amazing to be able to use it in detail. The intuition is as elegant as you can, and the other person's cheeks are fragrant, so they are fond of traveling and traveling!

Before engin is triggered, the only listener: enginconfig bound to engin is activated.
Basically, this enginconfig class does not do anything, that is, it sets the debug level of enginconfig to the same as that of Engin. In addition, several lines of text are output, indicating that engin has been configured and has not done any substantive work.
NOTE 1: The mapping component is useful when a requirement is to be passed from the parent container to the sub-container, and the parent container has multiple sub-containers, which sub-container should be selected to handle the requirements? This is determined by the mapping component.

4. Host
Like Engin, the START () method in containerbase is also called. However, some self-defined tasks have been done before, which is to install
"Org. Apache. Catalina. Valves. errorreportvalve" valve.
The purpose of this valve is as follows: after the requirement is passed to the host by Engin, it will continue to be passed to the context for specific processing. The requirement here is actually the request and response passed as the parameter. Therefore, after the context completes processing the requirement, the response is usually changed. However, the role of org. Apache. Catalina. Valves. errorreportvalve is to check whether the response contains errors. If yes, handle the errors accordingly.
5. Context
At this point, we finally reached the main point in Tomcat startup and started context.
Standardcontext. Start () is called by standardhost to start the context container.
5.1 webappresources specific directory to which the context points
5.2 concontex is installed. defacontext context is the default context. If defaultcontext is installed under a host and a database connection pool resource is installed in defaultcontext. All other context under the host can directly use the database connection pool without additional configuration.
5.3 specify loader. The default org. Apache. Catalina. loader. webapploader class is usually used. Loader is used to specify the classes and jar packages used in this context.
5.4 specify the manager. The default org. Apache. Catalina. session. standardmanager is usually used. Manager is used to manage sessions.
In fact, session management is also well implemented. Take a simple session management as an example. When the request is passed, there is a sessionid attribute in the request object. OK. After we get this sessionid, we can use it as the map key, and we can place the value in a hashmap. hashmap, and then put what we want to put.
5.5 there is a work directory under postworkdirectory (). tomcat. We threw all the temporary files there. This step is to create a directory there. Generally, a directory is generated in % catalina_home %/work/standalone \ localhost.
5.6 binding thread. Here, Class Loader swaps should occur. We can see all the classes and Lib under Tomcat before. Next we need to see the classes under the current context. Therefore, you must set contextclassloader and record the old classloader, because it will be used later.
5.7 start loader. Specify the specific classes and jar files used in the context. If reloadable is set to true, a thread is started to monitor classes changes. If there is any change, context is restarted.
5.8 start Logger
5.9 trigger a listener installed on it.
Lifecycle. firelifecycleevent (start_event, null );
As one of the listeners, contextconfig will be started. contextconfig is used to configure web. xml. For example, how many servlets and filters are contained in the context are installed in the context.
5.9.1 defaultconfig. The tomcat/CONF/Web. xml file must be configured for each context.
5.9.2 applicationconfig configure your own WEB-INF/Web. xml file
5.9.3 validatesecurityroles permission verification. When accessing/admin or/manager, users must be either admin or manager. In addition, we can restrict the resources that can be accessed, but which cannot. All are implemented here.
5.9.4 tldscan: Tag lab)
5.10 start Manager
5.11 postwelcomefiles:
Index.html#index.htm and index. jsp are bound to this context by default.
5.12 listenerstart configure listener
5.13 filterstart configure Filter
5.14 start a servlet with <load-on-startup>; 1 </load-on-startup>.
The order is from small to large: 1, 2, 3... Last 0
By default, at least three servlets are started:
Org. Apache. Catalina. servlets. DefaultServlet
Servlet for processing static resources. What images? HTML? CSS? JS? Look for him?
Org. Apache. Catalina. servlets. invokerservlet
Process the servlets that are not engaged in Servlet Mapping.
Org. Apache. Jasper. servlet. jspservlet
Process.
5.15 The context has been started.
How many steps have been taken? The context is finally started.
OK! Here, each container and component is started. Tomcat has finally worked tirelessly to serve the people!
3. References:
<Http://jakarta.apache.org/tomcat/>;
<Http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html>;

4. Postscript
This article explains the Tomcat startup framework and the details of the Message Processing Process in Tomcat. The content of the article has been written and is being sorted out. I believe it will soon be possible for everyone to study and make progress together.
This article is written by analyzing the source code of Tomcat on its own. Therefore, it must be subjective and sometimes one-sided. If there are any mistakes, please criticize and advise. This will not only allow the younger siblings who have just started to study tomcat to take a detour, but also allow me to learn something.
 
5. Tomcat source code analysis (Message Processing)
 
[ZT] Tomcat source code analysis
0: Preface
We know the overall framework of Tomcat and what components are in it and what they are used.
 
Http://www.csdn.net/Develop/read_article.asp? Id = 27225
 
I think, next we should look at how Tomcat handles JSP and Servlet requests.
 
 
 
1. Let's take a specific example to track Tomcat and see how it submits the request to the next container layer by layer and finally to wrapper for processing.
 
Take http: // localhost: 8080/web/login. jsp as an Example
 
(The following examples are based on Tomcat 4 source code)
 
 
 
This article is divided into three parts: the early stage, the middle stage, and the end stage.
 
Early stage: explains how to get caught by Tomcat by entering a URL in the browser.
 
Mid-term: explains how to get caught by tomcat in various containers and finally reach the final processing location.
 
End stage: explains how to handle the problem after arriving at the final processing location.
 
2. Born.
 
Here I will briefly talk about the request.
 
Let's first look at this URL: http: // localhost: 8080/web/login. jsp, which uses port 8080 for socket communication.
 
We know that through
 
Inputstream in = socket. getinputstream () and
 
Outputstream out = socket. getoutputstream ()
 
The message can come and go.
 
However, it is obviously inconvenient to operate a stream on the application layer.
 
Therefore, in Tomcat Connector, the socket is encapsulated into the request and response objects.
 
We can simply regard the request as the data sent to the server and the response as the data to be sent to the server.
 

 
But is there another problem? The request object encapsulates the socket, but it provides too many things.
 
Such as request. getauthorization () and request. getsocket (). Similar to authorization, developers are not very familiar with it, but it is potentially dangerous to expose something like socket to developers. In addition, the standard communication classes in servlet specification are servletrequest and httpservletrequest, rather than the request class. So, so, so. Tomcat must hold the request. At last, Tomcat chose to use the tamping mode (which should be called the adapter mode) to solve this problem. It sets org. Apache. Catalina. Request
It became org. Apache. Coyote. tomcat4.coyoterequest. Coyoterequest implements the servletrequest and httpservletrequest interfaces. This provides the methods that developers need and need.
 
 
 
OK. Let's set a breakpoint in the invoke () method of standardengin, the top-level container of Tomcat, and then access
 
Http: // localhost: 8080/web/login. jsp. Let's take a look at what will pass by in the early stage:
 
1. Run (): 536, java. Lang. Thread, thread. Java
 
Currentthread
 
2. Run (): 666, org. Apache. tomcat. util. threads. threadpool $ controlrunnable, threadpool. Java
 
Threadpool
 
3. Runit (): 589, org.apache.tomcat.util.net. tcpworkerthread, pooltcpendpoint. Java
 
Threadworker
 
4. processconnection (): 549
 
Org. Apache. Coyote. http11.http11protocol $ http11connectionhandler, http11protocol. Java
 
HTTP Protocol Parser
 
5. Process (): 781, org. Apache. Coyote. http11.http11processor, http11processor. Java
 
HTTP request processor
 
6. Service (): 193, org. Apache. Coyote. tomcat4.coyoteadapter, coyoteadapter. Java
 
Adapter
 
7. Invoke (): 995, org. Apache. Catalina. Core. containerbase, containerbase. Java
 
Standardengin
 
 
 
1. Main thread
 
2. Start the thread pool.
 
3. Call up idle working threads in the thread pool.
 
4. pass port 8080 to the data encapsulated by the httpd protocol and parse it into the request and response objects.
 
5. Use http11processor to process the request
 
6. In http11processor, call coyoteadapter to adapt the request to coyoterequest that implements the servletrequest and httpservletrequest interfaces.
 
7. At this point, the preliminary work of skin removal is basically done, and it can be handed over to standardengin for core processing.
 
 
 
3. middle stage. Shuttle between containers.
 
The following method is used to shuttle requests between containers:
 
Each container has a pipeline used to send requests.
 
There are several valves in the pipeline, which are used to filter requests.
 
A default valve is usually placed at the lower part of the pipeline. The valve will do at least one thing, that is, hand the request to the sub-container.
 
Let's imagine:
 
When a request enters a container, it flows in the pipeline ~ Boro ~ Boro ~ Ground through each valve. When it comes to the last valve ~ The damn valve threw it to the sub-container. And then begin Boro ~ Boro ~ Boro ~ ~.... Boro ~ Boro ~ Boro ~ ~....
 
In this way, the request completes all the containers. (It feels a bit like a digestive system, and the last place is a bit like it ~ )
 
OK. Let's take a look at the specific containers and the valves in each container. What have these valves done to our request:
 
 
 
3.1 In the pipeline of standardengin, it is: standardenginvalve
 
Here, valve does three things:
 
1. verify whether the passed request is httpservletrequest.
 
2. verify whether the passed request carries the Host header information.
 
3. Select the corresponding host to process it. (Generally, we only have one host: localhost, that is, 127.0.0.1 ).
 
At this point, our request has completed the historical mission of the engin part and the next stop to the future: host.
 
 
 
3.2 In the pipline of standardhost, it is: standardhostvalve
 
1. verify whether the passed request is httpservletrequest.
 
2. Determine which context to process based on the request.
 
Context is actually a webapp, such as http: // localhost: 8080/web/login. jsp
 
Here, the Web is context!
 
3. Now that you have determined the context, you should pay the classloader of the context to the current thread.
 
Thread. currentthread (). setcontextclassloader (context. getloader (). getclassloader ());
 
In this way, the request can only see the classes and jar under the specified context, but not the Tomcat class, what engin and valve. Otherwise, you still have it!
 
4. Now that the request has arrived, it seems that the user is preparing to access the Web web app. Why should we update the user's session! OK. The manager updates the user's session information.
 
5. submit it to the specific context container to continue processing the request.
 
6. After the context processing is complete, return the classloader.
 
 
 
3.3 The pipline in standardcontext is: standardcontextvalve
 
1. verify whether the passed request is httpservletrequest.
 
2. If the request is not intended, you want to access the items in the/meta-INF and/Web-INF directories!
 
3. At this time, it is determined which wrapper is used to process the reqeust based on whether the request is a servlet, JSP, or static resource.
 
4. Once you decide which wrapper to use, OK should be handed over to the wrapper for processing.
 
 
 
4. Final stage. How are different requirements handled.
 
Standardwrapper
 
I have not explained wrapper before, but it is actually such a thing.
 
We can divide the request into three types.
 
Handle static: org. Apache. Catalina. servlets. DefaultServlet
 
Processing JSP: org. Apache. Jasper. servlet. jspservlet
 
Processing servlet: org. Apache. Catalina. servlets. invokerservlet
 
Different requests are processed using these three different servlets.
 
Wrapper is a simple encapsulation of them. With wrapper, we can easily intercept each request. You can also easily call the servlet Init () and destroy () methods to facilitate management!
 
The specific situation is as follows:
 
If the request is for a JSP file, the standardwrapper encapsulates org. Apache. Jasper. servlet. jspservlet to process it.
 
If the request is for a static resource, the standardwrapper encapsulates org. Apache. Jasper. servlet. DefaultServlet to process it.
 
If the request is a servlet, The standardwrapper encapsulates org. Apache. Jasper. servlet. invokerservlet to process it.
 
 
 
Standardwrapper is also a container. Since it is a container, there must be a pipeline in it for the request to wear. There must also be a valve in the lower part of the pipeline (note 1 ), used for the last interception.
 
At the bottom of the valve, there are actually two main tasks:
 
One is to start the filter and let the request be screened in N filters, if OK! Pass. Otherwise, it will jump to another place.
 
The second is servlet. Service (httpservletrequest) request, (httpservletresponse) response); this method.
 
For jspservlet, compile the JSP file into servlet_xxx, and then invoke servlet_xxx's servie () method.
 
For DefaultServlet, you can directly find the static resource, retrieve the content, and send it out.
 
For invokerservlet, call the service () method of the specific servlet.
 
OK! Complete.
 
NOTE 1: The valve in standardwrapper is the last pass. If this valve wishes to deliver the request to the sub-container of standardwrapper for processing. Sorry, during design consideration, wrapper will be considered as the last container, and the root cause will not be the chance to add sub-containers to wrapper! If you want to call addchild (), immediately throw illegalargumentexception!
 
Refer:
 
<Http://jakarta.apache.org/tomcat/>;
<Http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html>;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.