Spring定时任务Scheduled在linux tomcat服务器上总是执行两次(tomcat配置)

时间:2022-01-12 07:47:47

Spring定时任务Scheduled在linux tomcat服务器上总是执行两次。 

在使用Spring定时任务Scheduled的时候,在本地Windows系统上,执行正常,但是在Linux生产环境上,总是启动两次,除了借助于redis以及线程安全来处理,使其只能执行一次意外,发现原因是tomcat的配置问题。 

 

Tomcat server.xml配置 

<?xml version="1.0" encoding="UTF-8"?> 

 

 <Server port="8005" shutdown="SHUTDOWN"> 

 <!-- Security listener. Documentation at /docs/config/listeners.html 

 <Listener className="org.apache.catalina.security.SecurityListener" /> 

 --> 

 <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/> 

 <Listener className="org.apache.catalina.core.JasperListener"/> 

 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/> 

 <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/> 

 <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/> 

 <GlobalNamingResources> 

 <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/> 

 </GlobalNamingResources> 

 

 <Service name="Catalina"> 

 

 <!-- 

 <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> 

 --> 

 

 <Connector connectionTimeout="20000" port="8764" protocol="HTTP/1.1" redirectPort="8443"/> 

 

 <!-- 

 <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 

 --> 

 <!-- 

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> 

 --> 

 

 <!-- Define an AJP 1.3 Connector on port 8009 --> 

 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/> 

 

 <!-- You should set jvmRoute to support load-balancing via AJP ie : 

 <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> 

 --> 

 <Engine defaultHost="localhost" name="Catalina"> 

 

 <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> 

 <Realm className="org.apache.catalina.realm.LockOutRealm"> 

 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> 

 </Realm> 

 

 <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> 

 <Context docBase="test" path="" reloadable="true"/> 

 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/> 

     </Host> 

 </Engine> 

 </Service> 

</Server> 

 

特别注意Host这部分配置 

Host可以理解为虚拟主机,对一个Tomcat,可以配置多台虚拟主机。简单地说,就是让一台服务器可以对应多个主机名。要求每个Host的Name必须唯一。但是只建议一个Tomcat只配置一个Host。 

Host的常用属性: 

Name:主机名,如localhost,test.com等 

appBase: 此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径,默认是tomcat的webapps 

autoDeploy:true,Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true; 

unpackWARs: 是否自动解压war包;默认为true; 

 

context类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序配置上下文,也就是对应主机下的具体子项目。 

context的常用属性: 

docBase: 相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径; 

path: 相对于Web服务器根路径而言的URI;如果为空"",则表示为此webapp的根路径; 

reloadable: 是否允许重新加载此context相关的Web应用程序的类;默认为false; 

 

特別注意这里的host和context配置,当未给Host配置Context时,Tomcat默认把ROOT项目作为Root Context,即此时访问 http://localhost:8080 就是访问ROOT项目,当给Host配置Context时,如果path="" 或 path="/",则相当于将此Context指定为Root Context,此时访问 http://localhost:8080 就是访问ROOT项目,如果在配置Context时,指定了path="" 或 path="/",同时又指定了docBase="test",则此时,在tomcat的webapps下会生成ROOT项目,并且在tomcat指定的appBase的路径下,生成一个同docBase相同名称的项目,这里就是test。此时,在tomcat里,就有了两个项目,启动tomcat,就相当于启动了两个端口相同的项目,如果使用了定时任务,则会同时执行两次。 

webapps下的ROOT是tomcat的应用程序的根,如果应用程序部署在ROOT中,则可直接通过http://ip:port 访问到