springboot:组件的可伸缩性

vi4fp9gy  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(263)

我正在尝试Spring Boot,并考虑可伸缩性。
假设我有一个执行任务的组件(例如,检查新邮件)。它是通过预定的方法完成的。
例如

@Component
public class MailMan
{
  @Scheduled (fixedRateString = "5000")
  private void run () throws Exception
  { //... }
}

现在应用程序获得了一个新客户。所以这项工作要做两次。
如何缩放此组件以使其存在或运行两次?

gjmwrych

gjmwrych1#

有趣的问题,但为什么每个客户有多个组件?调度器不能在计划运行时提取每个客户的数据并处理每个客户的记录吗?组件的扩展不应基于应用程序中演化的实体,而应基于组件的资源利用率。您可以使用专用的组件类型来处理队列的消息,也可以使用相同的组件类型来处理rest。根据每个资源的利用率来衡量它们。

t5zmwmid

t5zmwmid2#

您可以通过使用 ScheduledTaskRegistrar . 您可以多次注册同一个bean,即使它是单示例。

public class SomeSchedulingConfigurer implements SchedulingConfigurer {

  private final SomeJob someJob; <-- a bean that is Runnable

  public SomeSchedulingConfigurer(SomeJob someJob) {
    this.someJob = someJob;
  }

  @Override
  public void configureTasks(@NonNull ScheduledTaskRegistrar taskRegistrar) {
    int concurrency = 2;
    IntStream.range(0, concurrency)).forEach(
      __ -> taskRegistrar.addFixedDelayTask(someJob, 5000));
  }

}

确保正在使用的线程执行器足够大,可以同时处理作业量。默认执行器只有一个thead:-)。请注意,这种方法有缩放限制。
我还建议在作业之间添加延迟或倾斜,以便不是所有作业都在同一时刻运行。
请参阅schedulingconfigurer和scheduledtaskregistrar。

gj3fmq9x

gj3fmq9x3#

即使有多个客户,作业也只需要运行一次。组件本身根本不需要缩放。它只是一种“信号”机制,表明某些逻辑需要在某个时刻运行。我会让组件非常精简,只调用所需的业务逻辑来处理其余的部分。

@Component
public class MailMan {

  @Autowired
  private NewMailCollector newMailCollector;

  @Scheduled (fixedRateString = "5000")
  private void run () throws Exception { 
      // Collects emails for customers
      newMailCollector.collect();
  }
}

如果您想为每个客户检查新的电子邮件,您可能希望避免在后端服务中使用计划任务,因为这将使实现非常不灵活。
最好让客户端调用一个端点来触发该逻辑。

相关问题