本文主要是介绍spring Scheduled多次执行问题 线上Case已解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
spring Scheduled多次执行问题 线上Case已解决
需求:对VIP即将到期的用户发送邮件通知,每天的9点半,17点半,22点执行一次
项目:springboot + tomcat
这里面涉及两个问题
第一:tomcat配置问题。
有很多公司可能会有多个项目部署在一个tomcat下面,例如两个域名service.xxx.com和manage.xxx.com都部署在tomcat下面。
我原来的tomcat/config/server.conf host部分配置文件是这样的,
<Host name="manage.XXX.cn" appBase=""unpackWARs="true" autoDeploy="true"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /><Context path="" docBase="D:\apache-tomcat-9.0.0.M10\webapps\manage.XXX.cn" reloadable="true"></Context></Host><Host name="service.XXX.cn" appBase=""unpackWARs="true" autoDeploy="true"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /><Context path="" docBase="D:\apache-tomcat-9.0.0.M10\webapps\service.XXX.cn" reloadable="true"></Context></Host>
原配置会导致项目被加载两次,由于本人技术有限,还不清楚tomcat的加载机制,以后会去深入学习。
但是查看了tomcat的官方文档:
path: Even when statically defining a Context in server.xml, this attribute must not be set unless either the docBase is not located
under the Host’s appBase or both deployOnStartup and autoDeploy are false. If this rule is not followed, double deployment is likely to result.假如docBase的目录已经在appBase配置的目录下,或者deployOnStartup与autoDeploy都为false,就不需要配置path属性。如果配置了,就极有可能导致双重部署的结果。
修改后:
<Host name="manage.XXX.cn" appBase=""unpackWARs="true" autoDeploy="false" deployOnStartup="false"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /><Context path="" docBase="D:\apache-tomcat-9.0.0.M10\webapps\manage.XXX.cn" reloadable="true"></Context></Host><Host name="service.XXX.cn" appBase=""unpackWARs="true" autoDeploy="false" deployOnStartup="false"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /><Context path="" docBase="D:\apache-tomcat-9.0.0.M10\webapps\service.XXX.cn" reloadable="true"></Context></Host>
第二:Scheduled cron表达式语法不熟悉,入坑了
我原来cron表达式的写法:@Scheduled(cron = “0 30,30,0 9,17,22 * * ?”)
我本以为这样会是每天9点半,17点半,22点执行一次,但实际上是9点,9点半,17点,17点半,22点,22点半各执行了一次。这里就是因为对语法不够了解,入了坑。
我的解决方法可能有点笨,就是写了三个Scheduled
@Scheduled(cron = “0 30 9 * * ?”)
@Scheduled(cron = “0 30 17 * * ?”)
@Scheduled(cron = “0 0 22 * * ?”)
推荐一个在线Cron表达式解析网址:http://cron.qqe2.com/
JAVA学无止境
这篇关于spring Scheduled多次执行问题 线上Case已解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!