Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 401|回复: 0

解决spring定时任务执行两次和tomcat部署缓慢的问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-6 17:13:59 | 显示全部楼层 |阅读模式

    spring定时任务执行两次

    问题重现和解析

    最近使用quartz定时任务框架,结果发现开发环境执行无任何问题,部署到服务器上后,发现同一时间任务执行了多次。经过搜索发现是服务器上tomcat的配置文件出现了问题。
    原来的配置文件——server.xml如下:

    <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>
    

    一个Host表示一个容器,里面可以包含若干个Context(应用)。上面这段配置文件意思就是:在tomcat中配置了两个容器,一个name=localhost,应用的根目录为webapps,并且会自动解压war包和自动部署。没有指定context,会把根目录下的所有web应用都部署,部署成功后,外网可以通过服务器IP+项目名来访问;另一个name=www.xxx.com,和第一个host不同在于,配置了主页web应用,且不需要跟项目名就可以访问。部署成功后可以通过域名+项目名访问,主页所在项目可以直接通过根域名访问。

    这个时候问题就来了,包含定时任务的项目部署在webapps目录下,tomcat中两个独立的容器都部署了一遍,相当于项目在服务器上的tomcat上部署了两次,两边同时会运行定时任务,指定的是同一个数据库。

    问题解决

    因此,为了尽可能不影响其他项目的正常访问,我做了折中,讲需要执行定时任务的项目单独部署在另一个文件夹中,例如webroot ,然后只使用域名那个host,配置文件修改后如下:

    <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>
    

    可以看到projectC是包含定时任务的项目。这样部署成功后,除了该项目只能通过域名访问之外,其余项目的访问方式和之前保持不变。同时问题解决,定时任务只执行一次。

    网上的另一种说法

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

    只有一个host,tomcat在启动时,会部署一次根目录下的所有项目,然后Context又会单独部署一次,所以也会导致定时任务执行2次。
    对于这种问题,解决的方案也有多种:

    1. 将huost的appBase设为空,将Context的Context 指向项目部署位置的绝对路径。
    2. 删除Context节点。

    tomcat部署缓慢的问题

    用的阿里云服务器,部署tomcat时速度非常慢,但是后来买的新阿里云又没有这个问题。部署项目后一直会在

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

    这里卡好几分钟才会继续下去。之前一直以为是服务器配置原因,后来无意中发现是jre的配置原因。参考了几篇博客,发现oracle在WebLogic的文档下Avoiding JVM Delays Caused by Random Number Generation给了原因和解决方案。

    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.

    意思就是:

    1. JVM上产生随机数的策略有两种:/dev/random 和/dev/urandom。
    2. tomcat或者WebLogic等web服务器在部署时需要等待若一段随机数产生的时间。unix平台下JVM默认采用的是安全性更好的/dev/random,但是潜在的会阻塞服务进程。
    3. 推荐使用/dev/urandom,产生随机数速度快,/dev/random需要时间间隔生成随机数,部署时间长。

    修改方式:

    1. 打开$JAVA_HOME/jre/lib/security/java.security文件。
    2. securerandom.source=file:/dev/random 修改为securerandom.source=file:/dev/urandom

    重启tomcat,三十秒部署成功,solve it

    参考文献

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-4 00:01 , Processed in 0.064120 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表