我正在编写一份应用程序来处理设备引发的事件(每小时100万)。一些事件将被聚合(并且具有很长的时间跨度(例如48小时)),其包含开始事件,状态(x次) - 事件和结束事件。其他是单一事件,可以立即处理。为了至少一次保证事件将被处理,我正在寻找akka-persistence。该应用程序的其他部分已经使用了akka和kafka。
我的目标解决方案应该包含一个持久性地图,事件可以通过eventId轻松选取。订单不太重要。完成处理事件后,可以将其从地图中删除(并且不应再保留)。
在找到的docs / examples中,我找到了满足每事件清除要求的队列示例,但是在简单查找方面很困难(队列必须循环才能找到事件)。为了满足我想到的使用地图的简单查找,使用PersistentActor特性和下面的一些数据库。但是,事件由sequencenumber清除(这将删除需要更多处理/等待其他事件发生的事件)。调查的另一个特性是AtLeastOnceDelivery,其交付确认符合要求,但是这一点在恢复时阻止,直到所有事件都被处理完毕。
关于如何在Akka实施持久性篮子活动的任何想法? (我正在使用scala btw)
答案 0 :(得分:1)
这样的事情会满足您的需求吗? 它可能不完全是你的逻辑,但基本上它接收一个新事件,坚持它收到事件然后使用id将事件保存到地图中的事实。 然后在某些时候(不确定如何触发事件处理)它会收到处理具有特定id的事件的命令。它坚持认为它应该处理事件,然后处理事件并将其从地图中删除。 这样,地图将在重新启动时恢复,并且您拥有尚未处理的所有活动,可通过ID访问。
class PersistentMapActor extends PersistentActor {
private var eventMap: Map[ Int, Event ] = Map[ Int, Event ]( )
override def receiveRecover: Receive = {
case NewEventSaved( payload: Event ) =>
eventMap = eventMap + ( (payload.eventId, payload) )
case EventHandled( eventId ) =>
eventMap = eventMap - eventId
}
override def receiveCommand: Receive = {
case SaveNewEvent( payload ) =>
persist( NewEventSaved( payload ) ) { persistedNewEvent =>
//Add new event to map
eventMap = eventMap + ( (payload.eventId, payload) )
}
case HandleEvent( eventId ) =>
val event = eventMap.get( eventId )
event.foreach { e =>
persist( EventHandled( eventId ) ) { persistedEvent =>
//Do stuff with the event
//Remove the event from the map
eventMap = eventMap - eventId
}
}
}
override def persistenceId: String = "PersistentMapActor"
}
object PersistentMapActor {
case class Event( eventId: Int, someField: String )
case class SaveNewEvent( payload: Event )
case class NewEventSaved( payload: Event )
case class HandleEvent( eventId: Int )
case class EventHandled( eventId: Int )
}