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

一、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 "%r" %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 "%r" %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次。

对于这种问题,解决的方案也有多种:

  • 将huost的appBase设为空,将Context的Context 指向项目部署位置的绝对路径。
  • 删除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.

意思就是:

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

修改方式:

  • 打开$JAVA_HOME/jre/lib/security/java.security文件。
  • 将securerandom.source=file:/dev/random 修改为securerandom.source=file:/dev/urandom
  • 重启tomcat,三十秒部署成功,solve it

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

您可能感兴趣的文章:

  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法
  • Spring Task定时任务的配置和使用详解
  • java中 spring 定时任务 实现代码
  • 详解spring多线程与定时任务
  • 在Tomcat中部署Web项目的操作方法(必看篇)
  • 如何把spring boot项目部署到tomcat容器中
(0)

相关推荐

  • 如何把spring boot项目部署到tomcat容器中

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 <packaging>war</packaging> 二.移除嵌入式tomcat插件 在pom.xml里找到spring-boot-starter-web依赖节点,在其中添加如下代码, <dependency> <groupId>org.springframework.boot</groupId> <artifactId&

  • 在Tomcat中部署Web项目的操作方法(必看篇)

    在这里介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Manager Web应用程序 一:部署解包的webapp目录 将Web项目部署到Tomcat中的方法之一,是部署没有封装到WAR文件中的Web项目.要使用这一方法部署未打包的webapp目录,只要把我们的项目(编译好的发布项目,非开发项目)放到Tomcat的webapps目录下就可以了.如下图所示: 这时,打开Tomcat服务器(确保服务器打开),就可以在浏览器访问我们的项目了,如下

  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法

    前言 最近在项目中使用到定时任务,之前一直都是使用Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能. 下面说一下两种方式在Spring Boot 项目中的使用. Spring Schedule 实现定时任务 Spring Schedule 实现定时任务有两种方式 1. 使用XML配置定时任务, 2. 使用 @Scheduled 注解. 因为是Spring Boot 项目 可能尽量避免使用XML配置的形式,

  • java中 spring 定时任务 实现代码

    复制代码 代码如下: import org.apache.log4j.*;public class TaskJob {       public static Logger log = Logger                     .getLogger(TaskJob.class);       public void SayHello() {              // TODO Auto-generated method stub              try {      

  • Spring Task定时任务的配置和使用详解

    记录下Spring自带的定时任务用法. spring中使用定时任务 基于xml配置文件使用定时任务 首先配置spring开启定时任务 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/

  • 详解spring多线程与定时任务

    本篇主要描述一下spring的多线程的使用与定时任务的使用. 1.spring多线程任务的使用 spring通过任务执行器TaskExecutor来实现多线程与并发编程.通常使用ThreadPoolTaskExecutor来实现一个基于线程池的TaskExecutor. 首先你要实现AsyncConfigurer 这个接口,目的是开启一个线程池 代码如下: package com.foreveross.service.weixin.test.thread; import java.util.co

  • spring定时任务执行两次及tomcat部署缓慢问题的解决方法

    一.spring定时任务执行两次 问题重现和解析 最近使用quartz定时任务框架,结果发现开发环境执行无任何问题,部署到服务器上后,发现同一时间任务执行了多次.经过搜索发现是服务器上tomcat的配置文件出现了问题. 原来的配置文件--server.xml如下: <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">

  • SpringBoot应用部署到Tomcat中无法启动的解决方法

    背景 最近公司在做一些内部的小型Web应用时, 为了提高开发效率决定使用SpringBoot, 这货自带Servlet容器, 你在开发Web应用时可以直接在本地像运行控制台应用一样启动,省去了重复部署的时间:配置上相比于SpringMVC也是有了大大的简化.SpringBoot的应用可以直接打成一个可运行的jar包, 你无需发愁为了不同应用要部署多个Tomcat.但是实际部署时你会发现打成Jar包的方式有一个致命的缺点, 当你改动了一个资源文件.或者一个类时, 打要往服务器重新上传全量jar包.

  • 有关tomcat内存溢出的完美解决方法

    tomcat内存溢出设置JAVA_OPTS 答案1 设置Tomcat启动的初始内存 其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4.可以利用JVM提供的-Xmn -Xms -Xmx等选项可 进行设置 三.实例,以下给出1G内存环境下java jvm 的参数设置参考: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -D

  • spring boot 打包jar jar没有主目录清单问题的完美解决方法

    1.在POM.xml文件下添加如下代码:注意:version.configuration.executions三个标签是我后来查找添加的,网上解决方案要么没有这三个要么不一样,我试了都不行,而且我在我电脑试了这三个标签必须有: 2.如果没有version标签会在生成时会报错. 3.如果没有configuration.executions两个标签生成的jar会报jar没有主目录清单错误: 哀  折腾一天,没办法谁让自己是小白那.还有一个主意的:packaging标签页必须有: <packaging

  • 腾讯云服务器tomcat端口无法访问的解决方法

    最近用腾讯云配置了服务器,在使用的时候发现tomcat端口无法访问,所以在网上找了点资料,一共有两种情况,下面总结一下,希望对大家有所帮助,也给自己留个笔记. 第一种情况: 如题:https://console.cloud.tencent.com/cvm/securitygroup需要去这个地址设置安全组. 说实话,一句mmp不知当讲不当讲.使用说明这块太乱了. 当然更改了安全组和防火墙还是不行.于是我查看Tomcat的记录,发现: /home/apache-tomcat-8.5.37/bin/

  • idea启动Tomcat时控制台乱码的解决方法(亲测有效)

    目录 前言 解决方法: 方法一: 方法二: 方法三: 方法四: 总结 前言 很多人在idea中启动项目时会出现控制台的中文乱码,其实也无伤大雅,但是本人看着不舒服所以在网上查找了一些方法和各位分享一下 解决方法: 方法一: 1.打开tomcat配置页面,Edit Configurations. 2.选择项目部署的tomcat,在配置项VM options输入框中输入-Dfile.encoding=UTF-8,点击Apply或OK即可. 3.修改idea设置里的文件编码格式为utf-8. 我修改了

  • spring cloud feign不支持@RequestBody+ RequestMethod.GET报错的解决方法

    1.问题梳理: 异常:org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported 很明显是最终feign执行http请求时把这个方法认定为POST,但feign client中又定义了RequestMethod.GET 或 @GetMapping,冲突导致报错 那么为什么feign会认为这个方法是post呢? 源码追踪: 1.我们从feignClient注解

  • idea日志乱码和tomcat日志乱码问题的解决方法

    1 idea启动tomcat乱码 遇到的问题: idea整合SSM项目,tomcat启动,启动时查看idea上的tomcat日志,出现乱码: 但是直接用tomcat 的 startup.bat启动,无乱码: 2,出现的原因: 查看tomcat/conf/logging.properties java.util.logging.ConsoleHandler.encoding = GBK 而本window系统使用的也是GBK编码,所以直接使用bat文件启动正常,但是idea上配置的是UTF-8,所以

  • iOS两丫技术之UILabel性能不够的解决方法

    目录 Async View Async Layer RunLoop 触发 事件的保存 YYLabel 主要参照 YYKit YYKit 博大精深,就像少林武功 Async View 为了异步 + runloop 空闲时绘制, 因为苹果的 UILabel 性能不够 6 Async Layer 思路: UI 操作,必须放在主线程, 然而图形处理,可以放在子线程, ( 开辟图形上下文,进行绘制,取出图片 ) 最后一步,放在主线程,就好了 layer.contents = image Custom Vi

  • AngularJS中update两次出现$promise属性无法识别的解决方法

    前言 本文主要介绍的是在AngularJS中update两次出现$promise属性无法识别的解决方法,下面话不多说,先来看看错误提示,然后再看看解决的办法吧. 一.错误信息如下: ERROR 2015-12-02 14:33:17,653 http-bio-8080-exec-42 o.s.s.r.i.e.InternalErrorExceptionMapper - Unrecognized field "$promise" (class com.inetpsa.fnd.rest.c

随机推荐