Analyze the working principle of Tomcat

Analyze the working principle of Tomcat

SpringBoot is like a giant python, slowly winding around us and paralyzing us. I have to admit that the use of SpringBoot has indeed improved work efficiency, but at the same time it has also made us forget a lot of skills. When I first entered the society, I still manually deployed Java Web projects through Tomcat and often performed performance tuning on Tomcat. In addition, you also need to sort out the relationship between the various Jars to avoid problems such as Jar loss and version conflicts that may cause service startup exceptions. Now, all these tedious and repetitive tasks have been handled by SpringBoot, and we can focus more on business logic. However, understanding Tomcat's working principle and request processing flow is as important as analyzing the Spring framework source code. At least interviewers particularly like to ask about these underlying principles and design ideas. I hope this article can give you some help.

Tomcat overall architecture

Tomcat is a free, open source, lightweight Web application server. It is suitable for use in small and medium-sized enterprise projects where the concurrency is not very high.

File directory structure

The following is the main directory structure of Tomcat 8

Table of contents Functional Description
bin Stores executable files, such as startup and shutdown
conf Stores configuration files, such as the core configuration file server.xml and the application's default deployment descriptor file web.xml
lib Store the jar packages required for Tomcat to run
logs Stores the running log files
webapps Stores the default web application deployment directory
work Temporary directory for storing web application code generation and compiled files

Functional component structure

Tomcat has two core functions: the connector responsible for receiving and responding to external requests, and the container responsible for processing requests. The connector and container complement each other and together constitute the basic web service. Each Tomcat server can manage multiple Services.

Components Function
Connector Responsible for receiving external feedback requests. It is the transportation hub between Tomcat and the outside world. It listens to the port to receive external requests, passes the processed requests to the container for business processing, and finally feeds back the results of the container processing to the outside world.
Container Responsible for internal processing of business logic. It is composed of four containers: Engine, Host, Context and Wrapper, which are used to manage and call Servlet related logic.
Service Web services provided to the outside world. It mainly includes two core components: connector and container, as well as other functional components. Tomcat can manage multiple Services, and each Service is independent of each other.

Tomcat connector core principle

Tomcat Connector Framework - Coyote

Connector core functions

1. Listen to network ports, receive and respond to network requests.

2. Network byte stream processing. Convert the received network byte stream into Tomcat Request and then into standard ServletRequest to the container. At the same time, convert the ServletResponse sent by the container into Tomcat Response and then into a network byte stream.

Connector module design

To meet the two core functions of the connector, we need a communication endpoint to listen to the port; a processor to process the network byte stream; and finally an adapter to convert the processed results into the structure required by the container.

Components Function
Endpoint Endpoint, used to handle the logic of socket receiving and sending. Internally, Acceptor listens for requests, Handler processes data, and AsyncTimeout checks request timeout. Specific implementations include NioEndPoint, AprEndpoint, etc.
Processor Processor, responsible for building Tomcat Request and Response objects. Specific implementations include Http11Processor, StreamProcessor, etc.
Adapter Adapter, which realizes the conversion between Tomcat Request, Response and ServletRequest, ServletResponse. This uses the classic adapter design pattern.
ProtocolHandler The protocol processor combines different protocols and communication methods into corresponding protocol processors. For example, Http11NioProtocol encapsulates HTTP + NIO.

The corresponding source package path is org.apache.coyote . The corresponding structure diagram is as follows

Tomcat container core principle

Tomcat container framework - Catalina

Container structure analysis

Each Service will contain a container. A container engine can manage multiple virtual hosts. Each virtual host can manage multiple web applications. Each web application will have multiple Servlet wrappers. The four containers, Engine, Host, Context and Wrapper, are in a parent-child relationship.

container Function
Engine Engine, manages multiple virtual hosts.
Host Virtual host, responsible for the deployment of Web applications.
Context Web application, including multiple Servlet wrappers.
Wrapper Wrapper, the bottom layer of the container. Encapsulates Servlet and is responsible for instance creation, execution, and destruction.

The corresponding source package path is org.apache.coyote . The corresponding structure diagram is as follows

Container request processing

The container's request processing process is to call the four containers, Engine, Host, Context and Wrapper, layer by layer, and finally execute the corresponding business logic in the Servlet. Each container will have a channel Pipeline, and each channel will have a Basic Valve (such as StandardEngineValve), which is similar to a gate used to process Request and Response. The flow chart is as follows.

Tomcat request processing flow

The above knowledge points have introduced in bits and pieces how a Tomcat processes a request. Simply put, the connector's processing flow + the container's processing flow = Tomcat's processing flow. ha! So the question is, how does Tomcat find the corresponding virtual site through the request path? How to find the corresponding Servlet?

Mapper Function Introduction

Here we need to introduce a component Mapper which is not introduced above. As the name suggests, its role is to provide routing mapping for the request path. The request URL is matched to determine which container handles the match. Each container has its own corresponding Mapper, such as MappedHost. I wonder if you have ever recalled the fear of being dominated by Mapper class not found. In the past, every time you wrote a complete function, you needed to configure the mapping rules in web.xml. As the file became larger and larger, various problems would arise.

HTTP Request Process

Open the server.xml file in the tomcat/conf directory to analyze a http://localhost:8080/docs/api request.

Step 1: The connector listens on port 8080. Since the requested port and the listening port are the same, the connector accepts the request.

Step 2: Because the default virtual host of the engine is localhost, and the directory of the virtual host is webapps. So the request found the tomcat/webapps directory.

Step 3: The parsed docs is the application name of the web program, which is context. At this time, the request continues to look for the docs directory under the webapps directory. Sometimes we also omit the application name.

Step 4: The parsed API is the specific business logic address. At this time, you need to find the mapping relationship from docs/WEB-INF/web.xml and finally call the specific function.

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">

 <Service name="Catalina">

	<!-- The connector listening port is 8080, and the default communication protocol is HTTP/1.1 -->
 <Connector port="8080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="8443" />
			 
	<!-- The default virtual host for the engine named Catalina is localhost -->
 <Engine name="Catalina" defaultHost="localhost">

	 <!-- A virtual host named localhost, whose directory is webapps-->
 <Host name="localhost" appBase="webapps"
  unpackWARs="true" autoDeploy="true">

 </Host>
 </Engine>
 </Service>
</Server> 

How to start the embedded Tomcat in SpringBoot

SpringBoot's one-click service startup function makes many friends who have just entered the society forget what Tomcat is. As hardware performance becomes higher and higher, ordinary small and medium-sized projects can be started directly with the built-in Tomcat. However, some larger projects may require Tomcat clustering and tuning, and the built-in Tomcat may not be able to meet the needs.

Let's first analyze how SpringBoot starts Tomcat from the source code. The following is the code for SpringBoot 2.x.

The code starts with the main method and executes the run method to start the project.

SpringApplication.run

Click into the run method and find the method to refresh the application context.

this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);

Click on the refreshContext method and find the refresh method. And look up layer by layer to find the method of its parent class.

this.refresh(context);

In the refresh method of the AbstractApplicationContext class, there is a line of logic that calls the child container to refresh.

this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();

Click on the onRefresh method and find the implementation method of ServletWebServerApplicationContext. I finally see hope here.

protected void onRefresh() {
 super.onRefresh();

 try {
 this.createWebServer();
 } catch (Throwable var2) {
 throw new ApplicationContextException("Unable to start web server", var2);
 }
}

Click on the createWebServer method and find the code for getting WebServer from the factory class.

if (webServer == null && servletContext == null) {
 ServletWebServerFactory factory = this.getWebServerFactory();
 // Get the web server 
 this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
} else if (servletContext != null) {
 try {
 // Start the web server
 this.getSelfInitializer().onStartup(servletContext);
 } catch (ServletException var4) {
 throw new ApplicationContextException("Cannot initialize servlet context", var4);
 }
}

Click on the getWebServer method and find the implementation method of TomcatServletWebServerFactory, which also has Jetty and Undertow. Basic connectors, engines, virtual sites, etc. are configured here.

public WebServer getWebServer(ServletContextInitializer... initializers) {
 Tomcat tomcat = new Tomcat();
 File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
 tomcat.setBaseDir(baseDir.getAbsolutePath());
 Connector connector = new Connector(this.protocol);
 tomcat.getService().addConnector(connector);
 this.customizeConnector(connector);
 tomcat.setConnector(connector);
 tomcat.getHost().setAutoDeploy(false);
 this.configureEngine(tomcat.getEngine());
 Iterator var5 = this.additionalTomcatConnectors.iterator();

 while(var5.hasNext()) {
 Connector additionalConnector = (Connector)var5.next();
 tomcat.getService().addConnector(additionalConnector);
 }

 this.prepareContext(tomcat.getHost(), initializers);
 return this.getTomcatWebServer(tomcat);
} 

After the service is started, the log will be printed

osbwembedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8900 (http)
o.apache.catalina.core.StandardService : Starting service [Tomcat]
org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
oacatalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal ...
oaccC[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
osweb.context.ContextLoader : Root WebApplicationContext: initialization completed in 16858 ms

END

The article ends here. I really can’t hold it any longer. I wrote all day over the weekend and still haven’t gotten to the source code part. I can only put it in the next chapter. If I write it again, it will be useless. Please point out if there is anything wrong.

The above is the detailed content of how Tomcat works. For more information about the working principle of Tomcat, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of Tomcat core components and application architecture
  • Detailed explanation of the startup principle of SpringBoot built-in tomcat
  • Tomcat parses XML and creates objects through reflection
  • Detailed analysis of the startup.bat principle in Tomcat
  • Detailed analysis of catalina.bat principle in Tomcat
  • Introduction to the principles, configuration, and use of Tomcat data sources
  • Detailed explanation of the implementation principle of Tomcat hot deployment
  • Analyze Tomcat architecture principles to architecture design

<<:  The difference and usage of Vue2 and Vue3 brother component communication bus

>>:  Why the table file size remains unchanged after deleting data in MySQL

Recommend

Implementation of new issues of CSS3 selectors

Table of contents Basic Selector Extensions Attri...

Pure CSS to modify the browser scrollbar style example

Use CSS to modify the browser scroll bar style ::...

A summary of the reasons why Mysql does not use date field index

Table of contents background explore Summarize ba...

Vue component to realize carousel animation

This article example shares the specific code of ...

10 very good CSS skills collection and sharing

Here, clever use of CSS techniques allows you to g...

Vue implements a simple magnifying glass effect

This article example shares the specific code of ...

Ansible automated operation and maintenance deployment method for Linux system

Ansible is a new automated operation and maintena...

Solution for FileZilla 425 Unable to connect to FTP (Alibaba Cloud Server)

Alibaba Cloud Server cannot connect to FTP FileZi...

Perfect Solution for No rc.local File in Linux

Newer Linux distributions no longer have the rc.l...

Super detailed steps to install zabbix3.0 on centos7

Preface Recently, part of the company's busin...

How to solve the 2002 error when installing MySQL database on Alibaba Cloud

The following error occurred while installing the...

Analysis of Linux Zabbix custom monitoring and alarm implementation process

Target Display one of the data in the iostat comm...