This is the 13th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

If the profile

In special situations, we may need to use external Tomcat to run programs, such as Alitomcat, so that we can schedule development projects or other special scenarios.

External Tomcat execution

The pom. XML file is first packaged in war and then excluded from the Tomcat dependencies built into SpringBoot’s Web project

Maven configuration Adjustment

Remove the Tomcat dependency or change the Scope of the Tomcat dependency to provide to remove the Tomcat dependency

<dependency>
γ€€γ€€<groupId>org.springframework.boot</groupId>
γ€€γ€€γ€€γ€€<artifactId>spring-boot-starter-web</artifactId>
γ€€γ€€γ€€γ€€<! -- Remove embedded Tomcat plugin -->
γ€€γ€€γ€€γ€€<exclusions>
γ€€γ€€γ€€γ€€γ€€γ€€<exclusion>
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€<groupId>org.springframework.boot</groupId>
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€<artifactId>spring-boot-starter-tomcat</artifactId>
γ€€γ€€γ€€γ€€γ€€γ€€</exclusion>
γ€€γ€€γ€€γ€€</exclusions>
</dependency>
Copy the code

Reintroduce tomcat dependencies:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <! -- You don't have to pack it in, other facilities will be provided. In fact, this dependency can theoretically participate in the compile, test, run cycle and so on. --> <scope>provided</scope> </dependency>Copy the code

Change the packaging mode to WAR

<packaging>war</packaging>
Copy the code

Adjust springBoot’s boot class

Inheritance org. Springframework. Boot. Web. Servlet. Support. SpringBootServletInitializer, realize the configure method:

Why inherit this class, SpringBootServletInitializer source annotation:

  • Note that a WebApplicationInitializer is only needed if you are building a war file and deploying it. If you prefer to run an embedded web server then you won’t need this at all.

  • Note that if you are building the WAR file and deploy it, you may need to WebApplicationInitializer. If you like running an embedded Web server, you don’t need this at all.

DemoApplication, let its implementation SpringBootServletInitializer, then rewrite the configure () method:

A way, to start the class inheritance SpringBootServletInitializer implementation configure:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        returnbuilder.sources(Application.class); }}Copy the code
Way two, add a class inherits SpringBootServletInitializer implementation configure:
public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        // Where application. class is the bootstrap class annotated with @springBootApplication
        returnbuilder.sources(Application.class); }}Copy the code

Matters needing attention
  • When external Tomcat deployment is used for access, the configuration in application.properties(or application.yml) will be invalid. Please use Tomcat port and project name under Tomcat or Webapps to access.
server.port=
server.servlet.context-path=
Copy the code
  • In order to prevent the problem that the project access resources cannot be loaded due to the application context, it is recommended to add the tag under the tag in the POM. XML file:
<build> <! <finalName>war package name </finalName> <plugins> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>Copy the code

  1. IDEA, run MVN clean,–> MVN package, wait until the project is successfully packaged, find the project file location under target demo.war, copy to tomcat/webapps directory,

  2. Using the Windows command line, start the Tomcat server, the project starts successfully, the spring flag appears.

  3. Access path :localhost:8080/${package file name}/ Request URL

  4. How to remove the WAR package name when accessing it?

How it works: The default ROOT directory of Tomcat is ROOT, which is actually useless in a production environment, so we can override the ROOT project with our own project

The operation process

  1. Delete all files and folders under ROOT.

  2. After decompressing the war package of our project, copy all files and subdirectories in the project directory to the ROOT directory. Or even worse, delete the ROOT directory and change the name of our project package to root. war and put it under webapps.

Principle: Virtual directories can be configured for Tomcat itself. The method is to add Context information under the node in server.xml.

For example, we can configure

, that we can address http://localhost:8080/abc to visit us in D: \ app \ the ABC project. We can change the path=”/ ABC “to path=””. This means mapping ABC to the root directory, and the access path becomes http://localhost:8080/.

Add a Context node as follows:

<Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="Interface" reloadable="true" /> <! --> </Host> </Engine>Copy the code

Spring Boot also provides support for JMX monitoring. JMX monitoring exposes the same information to the outside world, but uses the MBeans container to encapsulate and manage application data.

  • Springboot’s JMX is enabled by default if Tomcat deploys two original Springboot war packages.

    • You need to add spring.jmx.enabled=false to the Application. Properties configuration for each project with JMX off;

    • Add spring.jmx.default-domain=project1 and spring.jmx.default-domain=project2 to each project to ensure that the domain is different.

The Tomcat configuration is modified

Change the default HTTP access port: 8080 to 8181, in tomcat8.5 / conf/server. The XML file modification: sample

<Connector port="8181" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
Copy the code

Example Change the default session validity period

In the tomcat/conf/web.xml file, the scope is project-specific: examples

    <session-config>
       <session-timeout>30</session-timeout>
    </session-config>
Copy the code

In tomcat/conf/server. The XML

<Context path="/test" docBase="/test"  
		γ€€γ€€defaultSessionTimeOut="3600" isWARExpanded="true"  
		γ€€γ€€isWARValidated="false" isInvokerEnabled="true"  
		γ€€γ€€isWorkDirPersistent="false"/>
Copy the code

In the Java backend code, you configure the session duration for a specific page

The session. SetMaxInactiveInterval (30 * 60);Copy the code

Effective priority: 3 > 2 > 1.

(Easter Egg) Tomcat tuning

Tomcat change the maximum thread, in the tomcat/conf/server. XML file: example


  • MaxThreads = “X” indicates that a maximum of X connections can be processed simultaneously
  • MinSpareThreads = “X” initializes X connections
  • MaxSpareThreads = “X” means that if there are a maximum of X threads, the threads that are not needed will be closed once the number exceeds X
  • AcceptCount = “X” acceptCount= “X” acceptCount= “X” When the number of concurrent connections reaches maxThreads. We don’t deal with anything above X

Tomcat memory optimization

  • Under Windows catalina. Bat
  • In Linux, catalina.sh is used as an example:

JAVA_OPTS= ‘-xMS256M -XMx512m’ -XMS JVM initialization heap size – Maximum Xmx JVM heap size The actual parameter size depends on the server configuration or project configuration.

Tomcat IO optimization
  1. IO (JAVA BIO) synchronizes and blocks. The server implementation pattern is one connection one thread. Of course, this can be improved by thread pooling.
    • BIO mode is suitable for small and fixed number of connections. This mode requires high server resources, and concurrency is limited to applications. It is the only choice before JDK1.4, but the program is intuitive, simple and easy to understand.
  2. JAVA NIO: Synchronous non-blocking IO, asynchronous blocking IO and BIO One Request One Thread Multiple Connections can be multiplexed using the same thread (multiplexing)
    • NIO mode is suitable for architectures with large number of connections and relatively short (light operation), such as chat server, concurrency is limited to the application, programming is more complex, JDK1.4 began to support.
  3. Asynchronous non-blocking IO(Java NIO2 aka AIO) is primarily different from NIO in terms of the underlying operating system. It can be compared to express delivery. NIO is to check whether the express delivery has arrived on the official website after shopping online (it may be many times), and then pick up the express delivery by yourself. AIO is a Courier delivering goods to your home (without paying attention to the delivery progress).
    • AIO mode is used for architectures with large number of connections and relatively long connections (heavy operation), such as album server, which fully calls the OS to participate in concurrent operation. The programming is complicated, and JDK7 began to support it.

In the server. In the XML

Implement I/O switchover for Tomcat

APR solves asynchronous I/O problems at the operating system level, dramatically improving performance (apr.apache.org/).)

  1. APR(Apache Portable Runtime) is a highly Portable library that is at the heart of Apache HTTP Server 2.x. Better integration with other native Web technologies, and overall making Java more efficient as a high-performance Web server platform rather than simply a backend container.
  2. In production environments, especially when using Tomcat directly as a WEB server, you should use Tomcat,Native, to improve its performance. Without the APR, almost 300 threads will fill up very quickly and future requests will have to wait. But with the APR, the number of concurrent threads drops significantly, from 300 to only a few dozen, and new requests come in without blocking.
  3. In the LOCAL area network environment test, even if 400 concurrent, is also an instant processing/transmission, but in the real Internet environment, page processing time only accounts for less than 0.1%, most of the time is used for page transmission. Without APR, a thread can only handle one user at a time, which is bound to block. So using APR in production environment is very necessary.