linux部署springboot项目,项目重复启动(定时任务执行两次)

时间:2024-03-20 21:54:59

springboot 定时任务部署至linux服务器上后会执行两次问题(以下分为两种原因)

springboot定时任务在本地运行时,正常执行且只执行一次,但是在maven打包成war包,部署至linux服务器上之后,定时任务奇怪的执行了两次。

由于未做负载均衡,所以可以先排除是因为多台服务器都运行此代码导致。

一、

参考了网上的一些资料后了解到,是因为定时任务被实例化了两次的缘故,这个现象归根到底问题出在tomcat的service.xml的配置上。

在service.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" />  
<Context docBase="emall" path="/" reloadable="true" />  
</Host>  

由于配置了appBase="webapps"和docBase="emall",原因是tomcat加载完appBase="webapps"之后又去加载docBase,因此造成加载两次项目的问题。

解决办法:

将 appBase="webapps"改成appBase="",将docBase="emall" 改成项目的绝对路径docBase="/usr/local/src/tomcat-emall/webapps/emall" ,这样,在tomcat启动后只会去加载一次docBase,重启tomcat,问题解决!!

参考:https://blog.csdn.net/yaobengen/article/details/70312663

后来发现了因为这样的配置出现的一下现象:

如果在webapps文件夹中没有emall项目文件夹(非压缩包),则在启动服务的时候会在tomcat根目录下生成一个ROOT的文件夹,里面则是emall项目的源文件。

如果在webapps文件夹下已经存在emall项目文件夹,则在启动服务的时候不会生成上述的ROOT文件夹,项目的源文件会在此emall文件夹下。

关于appBase与docBase的区别与联系,可以参考https://blog.csdn.net/chenxiaodan_danny/article/details/45397765

二、

以上原因如果无效的话,可参照以下情况:

项目打war包,pom中屏蔽掉springboot内置的tomcat

linux部署springboot项目,项目重复启动(定时任务执行两次)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

linux部署springboot项目,项目重复启动(定时任务执行两次)

@SpringBootApplication
@EnableScheduling
@EnableSwagger2
//public class MyyWaterinfoApplication extends SpringBootServletInitializer implements CommandLineRunner {
public class MyyWaterinfoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyyWaterinfoApplication.class, args);
    }

    // 需要把web项目打成war包部署到外部tomcat运行时需要改变启动方式
//    @Override
//    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//        this.setRegisterErrorPageFilter(false);
//        return builder.sources(MyyWaterinfoApplication.class);
//    }

    // springboot运行后此方法首先被调用
    // 实现CommandLineRunner抽象类中的run方法
//    @Override
//    public void run(String... args) throws Exception {
//        System.out.println("Report time for you: " + new Date().toString() + " ---> darling~ yours springboot2.0 project has been successfully started!nice day,right?");
//    }