Akka-Distributed Publish Subscribe in Cluster

Distributed Publish Subscribe in Cluster

如何将消息发送给不知道运行在哪个节点上的Actor?

如何将消息发送给群集中对指定topic注册的所有Actor?

此模式提供了一个中介actor——akka.cluster.pubsub.DistributedPubSubMediator,它管理actor引用的注册表,并将这些条目复制到所有群集节点或用特定角色标记的一组节点。

DistributedPubSubMediator actor应该在集群中的所有节点或具有指定角色的所有节点上启动。 mediator可以使用DistributedPubSub扩展或作为普通的actor来启动。

注册表最终是一致的,即在其他节点上不会立即看到更新,但通常在几秒钟之后它们会被完全复制到所有其他节点。 更新只能在自己那部分的注册表执行,并且这些更新是版本化的。 版本是以可扩展的方式通过Gossip协议传播到其他节点。

WeaklyUp状态的群集成员将参与Distributed Publish Subscribe,即,如果发布者和订阅者位于网络分区的同一侧,那么处于WeaklyUp状态的节点上的订阅者将收到发布的消息。

您可以通过任何节点上的mediator将消息发送到任何其他节点上注册的actors。

有两种不同的消息传递模式,在下面的“Publish and Send ”部分进行了解释。

1.Publish

这是真正的发布/订阅模式。 这种模式的典型用法是即时通讯应用程序中的聊天室。

Actors 被注册到一个指定的topic。 每个节点上会有许多订阅者。 该消息将被传递给该topic的所有订阅者。

为了提高效率,消息通过总线在每个节点(具有匹配的topic的节点)仅被发送一次,然后被传递给所有本地topic表示的订阅者。

使用DistributedPubSubMediator.Subscribe将actor注册到本地mediator。 成功订阅和取消订阅将通过DistributedPubSubMediator.SubscribeAck和DistributedPubSubMediator.UnsubscribeAck进行确认。 确认表示订阅已注册,但在复制到其他节点之前仍需要一些时间。

通过发送DistributedPubSubMediator.Publish消息到本地mediator来发布消息。

Actors在终止时会自动从注册表中删除,或者您可以使用DistributedPubSubMediator.Unsubscribe显式删除条目。

订阅者Actor的一个例子:

订阅者Actor可以在集群中的多个节点上启动,并且全部都将接收发布到“content”-topic的消息。

一个简单的actor,发布消息到“content”-topic:

它可以从群集中的任何位置将消息发布到该topic:

Topic Groups

Actors也可以订阅具有gorup id的指定topic。 如果使用gorup id进行订阅,则每个发布到sendOneMessageToEachGroup标志设置为true的topic的消息都会通过提供的RoutingLogic(默认随机)传递给每个订阅组中的某一个Actor。

如果所有订阅的Actors具有相同的gorup id,则这与发送一样,每个消息仅被递送给一个Actor。

如果所有订阅的aActors都有不同的组名,那么这就像正常的Publish一样工作,每个消息都被广播给所有的Actors。

注意:

请注意,如果使用gorup id,则它是topic标识符的一部分。 使用sendOneMessageToEachGroup = false发布的消息将不会传递给订阅了gorup id的订阅者。 使用sendOneMessageToEachGroup = true发布的消息将不会传递给未订阅gorup id的订阅者。

 

2.Send

这是一个点对点的模式,每个消息都被传送到一个目的地,但是你仍然不需要知道目的地的位置。 这种模式的典型用法是在即时通讯应用程序中与另一个用户进行私聊。 它也可以用于将任务分配给注册的工作人员,就像是routees可以动态地将自己注册到集群感知路由器(cluster aware router)。

消息将被传递给一个具有匹配路径的收件人,如果在注册表中存在的话。 如果多个条目与路径相匹配(因为它已在多个节点上注册),则消息将通过提供的RoutingLogic(默认随机)发送到其中一个目标。 消息的发送者可以指定本地actor是优选的,即,如果存在任何这样的mediator actor,则将消息发送给与所使用的mediator actor相同的本地Actor System中的Actor,否则路由到任何其他匹配的条目。

使用DistributedPubSubMediator.Put注册actor到本地mediator。 Put中的ActorRef必须属于与mediator具有相同的本地Actor System。 没有address信息的路径是发送消息的关键。 在每个节点上,给定路径只能有一个actor,因为路径在一个本地Actor System中是唯一的。

您可以通过发送DistributedPubSubMediator.Send消息到具有目标Actor的路径(没有address信息)的本地mediator。

Actors在终止时会自动从注册表中删除,或者您可以使用DistributedPubSubMediator.Remove明确删除条目。

目标Actor的一个例子:

目标Actor可以在集群中的多个节点上启动,并且都将接收发送到路径的消息(不包含address信息)。

一个Actor发送消息到目标Actor的路径:

它可以从群集中的任何位置将消息发送到目标Actor的路径:

也可以向通过DistributedPubSubMediator.Put注册的Actor广播消息。 将DistributedPubSubMediator.SendToAll消息发送到本地mediator,然后将包裹的消息传递给具有匹配路径的所有Actor。 具有相同路径(不包括地址信息)的Actor可以在不同的节点上注册。 在每个节点上只能有一个这样的Actor,因为路径在一个本地Actor System内是唯一的。

这种模式的典型用法是将消息广播到具有相同路径的所有副本,例如, 3个不同节点上的Actor都执行相同的操作,以实现冗余。 也可以选择指定一个属性(allButSelf)来决定是否将消息发送到自身节点上的匹配路径。

3.DistributedPubSub Extension

在上面的示例中,mediator是以akka.cluster.pubsub.DistributedPubSub扩展启动和访问的。 在大多数情况下,这很方便,也很完美,但是知道可以以普通Actor的身份启动mediator actor,并且可以同时拥有多个不同的mediator,以便能够将大量的actor/topic给不同的mediator。 例如,您可能希望为不同的mediator使用不同的集群角色。

可以使用以下属性配置DistributedPubSub扩展:

建议通过在akka.extensions配置属性中定义启动Actor System时所加载的扩展。 否则,它会在第一次使用时才被激活,然后需要一段时间才能被填充。

4.Delivery Guarantee

就像Akka的消息传递可靠性一样(Message Delivery Reliability),DistributedPubSub模式下的消息传送保证是最多一次传送。 换句话说,消息会通过线路丢失。

如果您正在寻找至少一次的交付保证,我们建议集成 Kafka Akka Streams integration

5.Dependencies

要使用Distributed Publish Subscribe,您必须在项目中添加以下依赖项。

 

 

知识共享许可协议
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

发表评论

电子邮件地址不会被公开。 必填项已用*标注