Axon 4.4 中文版文档(八)

八、截止时间

Axon框架中的“截止时间”概念是一种机制,允许在一定时间后执行某些操作。这次执行的背景是一个聚合或一个saga,其中规定了最后期限。如果最后期限过时,也有可能取消

参考指南的这一部分旨在详细介绍Axon框架提供的帮助安排和处理截止时间的功能。

8.1截止时间管理器

截止时间可以从saga和聚合中制定。DeadlineManager组件负责制定截止时间,并在达到截止时间时调用@deadlinehandler。DeadlineManager可以作为资源注入。它有两种风格:SimpleDeadlineManager和QuartzDeadlineManager

8.1.1制定截止时间

可以通过提供触发截止时间的持续时间(或触发时间)和截止时间名称来制定截止时间。

预定事件或预定截止时间

与事件调度不同,当触发截止时间时,不会存储已发布的消息。调度/触发截止时间不涉及EventBus(或EventStore),因此不会存储消息。

class DeadlineSchedulingComponent {

    void scheduleMyDeadline() {

        String deadlineId =

            deadlineManager.schedule(Duration.ofMillis(500), "myDeadline");

        // For example store the `deadlineId`

    }

}

同时,我们也收到一个可以用来取消截止时间的截止时间ID。在大多数情况下,将这个deadlineId作为一个字段存储在Aggregate/Saga中是最方便的。当某个事件意味着先前计划的截止时间已经过时(例如,有支付发票的截止时间,但客户支付了金额,这意味着截止时间已过时,可以取消),取消截止时间可能会很方便。

class DeadlineCancelingComponent {

    void cancelMyDeadline(String deadlineId) {

        deadlineManager.cancelSchedule("myDeadline", deadlineId);

    }

}

请注意,在前面提到的方法旁边有更多取消截止时间的选项:

  1. cancelAll(String deadlineName):取消与给定死线名称匹配的每个预定截止日期。请注意,这也会取消其他与名称匹配的聚合和/或saga实例的截止日期。
  2. cancelAllWithinScope(String deadlineName):在调用方法的范围内,取消与给定死线名称匹配的预定截止日期。例如,如果此操作是从“聚合实例X”中执行的,“aggregate instance X”中的ScopeDescriptor将用于取消。
  3. cancelAllWithinScope(字符串死线名称,ScopeDescriptor范围)取消与给定deadlineName和ScopeDescriptor匹配的计划截止日期。这允许从不同的范围(而不是在其中执行)中按名称取消截止日期。

如果在处理截止时间时需要有关截止日期的上下文数据,则可以在安排截止时间时附加截止时间负载:

class DeadlineSchedulingWithPayloadComponent {

    void scheduleMyDeadlineWithPayload() {

        String deadlineId = deadlineManager.schedule(

            Duration.ofMillis(500), "myDeadline",

            new MyDeadlinePayload(/* some user specific parameters */)

        );

        // For example store the `deadlineId`

    }

}

8.1.2处理截止时间

我们现在已经知道如何设置最后期限了。当满足计划时间时,将调用相应的@DeadlineHandler。@DeadlineHandler是一个消息处理程序,与Axon中的任何其他处理程序一样,可以为存在parameterResolver的参数注入参数。

期限的范围

在制定最后期限时,会考虑到上下文。这意味着预定的截止日期只会在其原始上下文中触发。因此,您希望在满足的截止日期调用的任何@DeadlineHandler注释函数都必须位于从中调度的相同聚合/Saga中。

Axon称此上下文为范围。如有必要,实现并提供自己的作用域将允许您在自定义的“限定范围”组件中安排截止日期。

@DeadlineHandler根据截止时间名称和截止时间负载进行匹配。

@DeadlineHandler(deadlineName = "myDeadline")

public void on(MyDeadlinePayload deadlinePayload) {

    // handle the deadline

}

如果在@DeadlineHandler中没有定义截止时间的名称,那么匹配将仅根据deadline有效负载继续。

@DeadlineHandler

public void on(MyDeadlinePayload deadlinePayload) {

    // handle the deadline

}

如果我们计划了一个没有特定负载的截止日期,那@DeadlineHandler不必指定负载。

 

@DeadlineHandler(deadlineName = "payloadlessDeadline")

public void on() {

    // handle the deadline

}

8.1.3在应用程序中使用时间

在需要访问时钟的情况下,可以利用时钟访问消息GenericEventMessage.clock. 这个钟设为时钟系统UTC在运行时进行操作,以模拟测试期间的时间。

public void handle(PublishTime cmd) {

    apply(new TimePublishedEvent(GenericEventMessage.clock.instant()));

}

请注意,当前时间戳会自动添加到EventMessage中。如果处理程序只需要依赖事件发布的时间戳,则可以直接访问该时间戳,如处理事件那一节中所述。

8.2事件执行计划

本节将继续使用EventScheduler处理截止日期时的建议操作过程。

为了更好地理解这一点,让我们以一个saga为例:当事件发生时,让一个saga采取行动是很容易的。毕竟,有一件事件要通知这个传奇。但是如果你想让你的saga在什么都没发生的时候做些什么呢?这就是截止事件的用途。对于发票,这通常是几个星期,而信用卡付款的确认应该在几秒钟内完成。

预定事件作为截止日期

在Axon中,可以使用EventScheduler来安排要发布的事件。在发票示例中,您希望发票在30天内支付。saga在发送CreateInvoiceCommand之后,会计划在30天内发布InvoicePaymentDeadlineExpiredEvent。EventScheduler在安排事件后返回ScheduleToken。此token可用于取消计划,例如在收到发票付款时。

Axon提供了三种EventScheduler实现:

  • 纯Java
  • 基于定时任务框架Quartz
  • 基于Axon服务器

EventScheduler的纯Java实现使用ScheduledExecutorService来安排事件发布。虽然这个调度程序的计时非常可靠,但它是一个纯内存实现。一旦JVM关闭,所有的时间表都会丢失。这使得这种实现不适合长期计划。SimpleEventScheduler需要配置一个EventBus和一个SchedulingExecutorService(请参阅java.util.concurrent.Executors类用于helper方法)。

QuartzEventScheduler是一个更可靠、更值得企业使用的实现。使用Quartz作为底层调度机制,它提供了更强大的特性,如持久性、集群和意外管理。这意味着事件发布是有保证的。可能有点晚了,但会出版的。它需要配置一个Quartz调度程序和一个事件总线。或者,您可以设置Quartz作业计划所在的组的名称,默认为“AxonFramework Events”。

AxonServerEventScheduler使用Axon服务器来计划要发布的事件。因此,使用Axon服务器作为事件存储解决方案来利用这个事件调度器是一个很难的要求。正如QuartzEventScheduler一样,AxonServerEventScheduler是EventScheduler接口的一个可靠且有企业价值的实现。创建一个AxonServerEventScheduler可以通过它的构建器完成,它的唯一需求就是AxonServerConnectionManager。

需要注意的是,QuartzEventScheduler和AxonServerEventScheduler都应该使用事件序列化器来序列化和反序列化计划的事件。如果调度程序使用的序列化程序与事件存储所使用的Seralizer不一致,则应该出现异常情况。Quartz实现的序列化器可以通过定义不同的EventJobDataBinder来设置,而Axon服务器实现允许直接通过构建器定义所使用的序列化器。

一个或多个组件将侦听计划的事件。这些组件可能依赖于绑定到调用它们的线程的事务。计划事件由EventScheduler管理的线程发布。要管理这些线程上的事务,可以配置TransactionManager或UnitOfWorkFactory,以创建绑定到事务的工作单元。

spring配置

Spring用户可以使用QuartzEventSchedulerFactoryBean或SimpleEventSchedulerFactoryBean来简化配置。它允许您直接设置PlatformTransactionManager。

依赖于Axon服务器的springboot用户不必定义任何东西。自动配置将自动为它们创建一个AxonServerEventScheduler。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值