Spring boot Web服务/微服务和调度

问题描述 投票:0回答:1

我有一个Spring Boot应用程序,它公开了REST API,并且还计划添加一个Spring Boot计划任务。

此任务的目的是从作为momgodb的数据存储中提取一些未决的“保留”并进行处理。

现在的问题是,当多个服务实例正在运行时,所有节点都很有可能会选择相同的'保留记录'。

我正在为此寻找mongodb锁,并正在检查mongodb的updateAndModidy /事务(在4.x中)。

也可以使用只有一个记录的单独锁定表,在此情况下,我锁定记录并执行操作并解锁记录。但是通过这种方式,一次只有一个节点可以正常工作,而且如果解锁操作失败,清理锁的开销也将很大。

因此问题涉及如上所述的运行和调度任务的服务的多个实例。我将不胜感激,如果任何人都可以针对此主题,无论技术(弹簧启动/ mongodb等)如何指向最佳实践或解决方案。

java spring mongodb spring-boot scheduling
1个回答
1
投票

取决于您的部署,一种适用于我们的解决方案是使用Hazelcast使用来自同一应用程序的节点创建群集,然后在运行任务时,所有节点检查它们是否为主节点,只有主节点才能运行任务。

您可以在此处阅读有关Hazelcast的春季介绍:https://josdem.io/techtalk/spring/spring_boot_hazelcast_es/

我们使用的是带有Consul的Hazelcast,因此我们不必使用以下命令手动配置ips /端口:https://github.com/bitsofinfo/hazelcast-consul-discovery-spi

如果您没有很多(动态)节点,那么这是一个相对简单的解决方案,对我们来说很好(3个节点,与詹金斯的consul / fabio协调零停机时间部署)

过去,我们曾经使用Quartz的通用JDBC数据源作为同步机制来让Quartz调度来协调所有节点,但是实现是错误的,并且时不时地,我们最终会遇到需要手动解锁的TABLE锁。 ,杀死一些节点。

欢呼声

编辑:

这是我们班上一位的样子:

// Optionally autowired, in case we don't run in a cluster (development)
private final Optional<HazelcastInstance> hazelcast;

    @Scheduled(cron = "${refresh.cron}")
    public void scheduledRefresh() {
        // Run if we are not in a cluster or 
        // we are the first member of the cluster
        if (!hazelcast.isPresent() || 
   hazelcast.get().getCluster().getMembers().iterator().next().localMember()) {
    // Run restricted method
   }
© www.soinside.com 2019 - 2024. All rights reserved.