Solution to the problem of spring timed tasks executing twice and tomcat slow deployment

  • 2021-01-06 00:36:20
  • OfStack

1. spring timed tasks are executed twice

Problem reproduction and resolution

Recently, using the quartz Timing Task Framework, I found that the development environment performed without any problems. After deploying to the server, I found that the task was executed multiple times at the same time. After searching, it is found that there is a problem with the tomcat configuration file on the server.

The original configuration file -- server.xml is as follows:


<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
  prefix="localhost_access_log" suffix=".txt"
  pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
<Host name="www.xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
 <Context path="" docBase="/usr/local/tomcat/apache-tomcat-8.5.9/webapps/xxxindex" reloadable="true"></Context> 
</Host>

An Host represents a container that can contain several Context (applications). name=localhost, the root directory of the application is webapps, and the application will automatically unpack the war package and automatically deploy it. If context is not specified, all web applications in the root directory will be deployed. After successful deployment, the extranet can be accessed via the server IP+ project name. web =www.xxx.com =www.xxx.com =www.xxx = web. After successful deployment, the project can be accessed through the domain name + project name. The project where the home page is located can be accessed directly through the root domain name.

The project containing the scheduled tasks is deployed in the webapps directory. In tomcat, two separate containers are deployed once, which is equivalent to the project being deployed twice on tomcat on the server. The scheduled tasks are run on both sides at the same time, specifying the same database.

Problem solving

Therefore, in order to minimize the impact on the normal access of other projects, I made a compromise by deploying projects that need to perform timed tasks in a separate folder, such as webroot, and then using only the domain name host. The configuration file was modified as follows:


<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
   prefix="localhost_access_log" suffix=".txt"
   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
<Host name="www.xxx.com" appBase="" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
 <Context path="" docBase="/usr/local/tomcat/apache-tomcat-8.5.9/webapps/xxxindex" reloadable="true"></Context> 
 <Context path="/projectA" docBase="/usr/local/tomcat/apache-tomcat-8.5.9/webapps/projectA" reloadable="true"></Context> 
 <Context path="/projectB" docBase="/usr/local/tomcat/apache-tomcat-8.5.9/webapps/projectB" reloadable="true"></Context> 
 <Context path="/projectC" docBase="/usr/local/tomcat/apache-tomcat-8.5.9/webroot/projectC" reloadable="true"></Context> 
</Host>

As you can see, projectC is a project with timed tasks. After this successful deployment, the project access mode remains the same as before, except that the project can only be accessed through the domain name. Timed tasks are executed only once while the problem is resolved.

Another way of saying it online


<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> 
 <Context docBase="projectA" path="" reloadable="true" /> 
</Host> 

There is only one host. When tomcat is started, all the projects in the root directory are deployed once, and then Context is separately deployed once, so the timed task is also executed twice.

For this kind of problem, there are many solutions:

Set appBase for huost to null and point Context for Context to the absolute path of the project deployment location. Delete the Context node.

2. Slow deployment of tomcat

The Ali cloud server used was very slow when deploying tomcat, but the new Ali cloud bought later did not have this problem. 1 will be there after the project is deployed

[

INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /opt/apache-tomcat-8.0.15-server/webapps/ROOT

]

It's going to be stuck for a few minutes. Previously 1 thought it was the server configuration, but later I found it was the jre configuration. Avoiding JVM Delays Caused by Random Random Number Generation is given the reasons and solutions in the documentation of WebLogic.

[

The library used for random number generation in Sun's JVM relies on /dev/random by default for UNIX platforms. This can potentially block the WebLogic SIP Server process because on some operating systems /dev/random waits for a certain amount of "noise" to be generated on the host machine before returning a result. Although /dev/random is more secure, BEA recommends using /dev/urandom if the default JVM configuration delays WebLogic SIP Server startup.

]

It means:

There are two strategies for generating random numbers on JVM: /dev/random and /dev/urandom. web servers, such as tomcat or WebLogic, need to wait for a random number to be generated during deployment. JVM is a more secure /dev/random platform by default, but it can potentially block the service process. It is recommended to use /dev/urandom to generate random numbers quickly. /dev/random requires time interval to generate random numbers and long deployment time.

Modification method:

Open $JAVA_HOME/jre lib/security/java security file. source=file:/dev/random has been modified to securerandom.source=file:/dev/urandom Restart tomcat, deployment successful in 310 seconds, solve it

conclusion


Related articles: