Shedlock with Spring Cloud Function @PollableBean

Shedlock with Spring Cloud Function @PollableBean

我最近将我们几乎所有服务的实施都切换到了 spring 云功能,这自然也意味着所有计划的工作都已转换为供应商,例如从这个

@Scheduled(cron = "${retry.job.cron.time}")
@SchedulerLock(name = "retryProcess_scheduledTask", lockAtMostFor = "${retry.job.lock.atMost}", lockAtLeastFor = "${retry.job.lock.atLeast}")
public void retryUnprocessedItems() { ...}

至此

@PollableBean
public Supplier<List<Message<ProductValidatedEvent>>> retryUnprocessedItems() { ... }

如您所见,这里唯一的障碍是实施某种分布式锁机制,以防止那些 PollableBean 注释 Suppliers 在所有服务实例上启动。

我考虑过将计划的作业恢复到它们原来的位置并使用 StreamBridge 来解决这个问题,但这听起来更像是一个 hack,而不是一个解决方案。

另一个想法是将供应商转换为 Function 接口类型,并通过正常的 @Scheduled 注释方法调用它,但这似乎与 Spring云功能也是如此。

有什么想法吗?

这真的很有趣。我看到有两种解决方法。

  1. 最直接的是在另一种方法上使用AOP
@PolllableBean
public Supplier<Void> retryUnprocessedItems(){ 
    return otherBean::doIt;
}

class OtherBean {
  @SchedulerLock(...)
  public void doIt() {
    ....
  }
}

请注意,该方法是在不同的 class 上实现的,以允许 AOP 工作。此外,我还必须将 return 类型更改为 Void,因为如果锁被锁定,我们不知道要 return 做什么。

  1. 另一种选择是使用 locking without framework

根据上面的 Lukas 回答,我已经能够更新我的代码,以便它使用 Spring AOP,我创建了一个 ScheduledTask 组件,只有一个方法包含 Supplier 逻辑,用 @SchedulerLock 注释标记,并将供应商稍后发出的值返回到 Kafka 主题

@Autowired
ScheduledTask task;

@PollableBean
public Supplier<String> getScheduledJob() {
    return task::fire;
}

@Slf4j
@Component
class ScheduledTask {
    @SchedulerLock(name = "myJobLock", lockAtMostFor = "10s", lockAtLeastFor = "1s")
    public String fire() {
        log.info("Task was fired");
        return (String.valueOf(System.currentTimeMillis()));
    }
}

您可以在此处找到 运行 示例 https://github.com/Mahm0ud/ShedlockWithSpringCloudFunction