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
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.
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.
The corresponding source package path is 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.
The corresponding source package path is 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
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:
|
<<: The difference and usage of Vue2 and Vue3 brother component communication bus
>>: Why the table file size remains unchanged after deleting data in MySQL
Table of contents Basic Selector Extensions Attri...
Use CSS to modify the browser scroll bar style ::...
Table of contents background explore Summarize ba...
This article example shares the specific code of ...
Here, clever use of CSS techniques allows you to g...
This article example shares the specific code of ...
Ansible is a new automated operation and maintena...
Alibaba Cloud Server cannot connect to FTP FileZi...
Newer Linux distributions no longer have the rc.l...
Preface Recently, part of the company's busin...
Preface When the system space usage is too large ...
The following error occurred while installing the...
Currently, Nginx has reverse proxyed two websites...
<button> tag <br />Definition and usag...
Target Display one of the data in the iostat comm...