【问题标题】:how to run scheduled task in one specific server with same codebase如何在具有相同代码库的特定服务器中运行计划任务
【发布时间】:2021-06-02 20:45:48
【问题描述】:

我正在开发一个 springboot 项目,该项目具有 REST API 和一些计划任务 (@Scheduled)。目前我们有两台服务器,我想在两台服务器上部署相同的代码。所以,我的要求是,一台服务器应该只服务 API 请求,而其他服务器应该只运行 cron 作业。 如何限制第一台服务器运行 cron 作业。

我可以想到一个解决方案,使用@Profile("{spring.profiles.active}") 标记调度程序类并使用 cron 配置文件进行部署。但我必须在 application.properties 中添加额外的 4 组配置文件。像 cron.prod、cron.dev、cron.qa、cron.stage。所以总共将是 8 组配置文件。

我在这里粘贴我现有的代码。 在 application.properties 中

myservice.lmsurl=${${spring.profiles.active}.myservice.lmsurl}
prod.myservice.lmsurl=https://test.com
qa.myservice.lmsurl=https://test.com
dev.myservice.lmsurl=https://test.com
uat.myservice.lmsurl=https://test.com

在 Appconfiguration.class 中

@Configuration
@ConfigurationProperties("myservice")

public class AppConfiguration {


    @NotEmpty
    private String lmsurl;
}

任何其他更好的解决方案。

【问题讨论】:

    标签: spring spring-boot spring-mvc cron


    【解决方案1】:

    您只需要“cron”配置文件。对于不同的环境(DEV、QA、..),您需要将属性的值外部化。

    例如 myservice.lmsurl=${myservice.lmsurl}

    然后Spring会级联查找值https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/boot-features-external-config.html

    例如,如果您在 Tomcat 中部署,您可以在 xml 文件中设置值。如果你在 AWS 中部署,你可以将其设置为环境变量,...

    当然,您还必须在此外部化配置中设置您要使用的配置文件:spring.profiles.active 以告知您是否要使用 cron。

    CRON 示例

    您的调度程序:

    @Component
    @Profile("cron")
    public class CronScheduler {
    
        @Scheduled(fixedDelay = 43200000)
        public void job1() {
            // some code
        }
    }
    

    仅当配置文件处于活动状态时才会加载此类。在你的 application.properties 你有:

    spring.profiles.active=${profiles.active}
    

    ${profiles.active} 引用外部属性。检查我提供的链接以了解外部配置是如何工作的。例如,如果你在 AWS 中部署,你可以通过控制台设置环境变量,如果你使用 Tomcat 部署,你将在 Tomcat/conf/Catalina/localhost 下有一个 XML 配置文件,...

    如果变量为空,则使用默认配置文件,并且不会加载标记为“cron”的类。

    关于不同的环境

    根据经验,您应该始终将不同环境的属性外部化。在您的情况下,它是 myservice.lmsurl。对于每个部署环境,此 url 都会发生变化。因此,它是一个很好的外部化候选人。 在你的 application.properties 你有:

    myservice.lmsurl=${myservice.lmsurl}
    

    ${myservice.lmsurl} 告诉 Spring 他必须在某个地方寻找这个值。位置顺序在我提供给 Spring 文档的链接中。 在您的每个环境中,您必须以与 ${profiles.active} 相同的方式定义值。

    Tomcat 示例,在 yourApplication.xml 中:

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
        <Environment name="profiles.active" value="cron" type="java.lang.String"/>
        <Environment name="myservice.lmsurl" value="https://test.com" type="java.lang.String"/>
    </Context> 
    

    这个EXTERNAL文件因环境而异。

    【讨论】:

    • 我没有完全理解。如果我只保留一个配置文件“cron”,那么对于不应运行 cron 的第一台服务器,哪个配置文件应该是活动的。如何指定不同的环境以及如何访问特定于环境的 url。您能否提供更多详细信息,例如我应该在 application.properties 中更改什么
    • 如果使用@Profile 标记类或方法,则只有在指定的配置文件处于活动状态时才会加载它。因此,在您的情况下,如果您不想激活调度程序,只需不要将 cron 指定为活动配置文件,它就不会在启动时加载。关于特定环境,由于您将属性外部化,因此您不必在应用程序 url 中指定任何内容。我会尝试用代码示例更新我的答案。
    • 我更新了我的答案。希望它更清楚。
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 2020-11-28
    • 2021-02-01
    • 1970-01-01
    • 2018-03-17
    • 2013-11-08
    • 2021-03-03
    • 2010-09-22
    相关资源
    最近更新 更多