简体   繁体   English

Shedlock 与 Spring 云 Function @PollableBean

[英]Shedlock with Spring Cloud Function @PollableBean

I have recently switched the implementation of almost all our services to spring cloud function, and naturally that mean as well that all scheduled jobs have been converted to suppliers, for example from this我最近将我们几乎所有服务的实施切换到 spring 云 function,这自然也意味着所有预定的作业都已转换为供应商,例如从这个

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

to this对此

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

As you can see the only obstacle here is implemented some sort of a distributed lock mechanism to prevent those PollableBean annotated Suppliers from starting on all service instances.正如您所看到的,这里唯一的障碍是实现了某种分布式锁机制,以防止那些PollableBean注释的Suppliers在所有服务实例上启动。

I have thought about reverting back the scheduled jobs to where they were and use StreamBridge to resolve this, but this sounded like a hack more than a solution.我曾考虑将计划的作业恢复到原来的位置并使用StreamBridge来解决这个问题,但这听起来更像是一个 hack,而不是一个解决方案。

Another Idea was to convert the supplier into a Function interface type, and call it through a normal @Scheduled annotated method, but this does not seems to set well with Spring cloud function as well.另一个想法是将供应商转换为Function接口类型,并通过正常的@Scheduled注解方法调用它,但这似乎与Spring云ZC1C425268E68385D1AB5074C17A9设置得不好。

Any Ideas?有任何想法吗?

this is really interesting.这真的很有趣。 I see two ways of solving this.我看到解决这个问题的两种方法。

  1. The most straigntforward is to use AOP on another method最直接的就是在另一种方法上使用AOP
@PolllableBean
public Supplier<Void> retryUnprocessedItems(){ 
    return otherBean::doIt;
}

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

please note that the method is implemented on different class to allow AOP to work.请注意,该方法在不同的 class 上实现以允许 AOP 工作。 Also I had to change the return type to Void as we would not know what to return in case the lock is locked.此外,我不得不将返回类型更改为Void ,因为如果锁被锁定,我们不知道要返回什么。

  1. The other option is to use locking without framework另一种选择是在没有框架的情况下使用锁定

Based on Lukas answer above, I have been able to update my code so that it uses Spring AOP, I have created a ScheduledTask Component with only one method that contains the Supplier logic, marked with @SchedulerLock annotation, and returning the value to be emitted by the supplier later on to the Kafka topic根据上面 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()));
    }
}

You can find a running sample here https://github.com/Mahm0ud/ShedlockWithSpringCloudFunction您可以在此处找到运行示例https://github.com/Mahm0ud/ShedlockWithSpringCloudFunction

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM