首页 > 解决方案 > 将事件发布到单个微服务实例

问题描述

我正在开发一个项目,该项目具有多个事件驱动的微服务,并且还使用 Kubernetes 进行负载平衡。所有的服务都是发布者和听众。当微服务发布事件时,所有侦听器都在捕获事件(如果它侦听该特定事件)并完成他们的工作。在此之前,此流程没有问题:

假设我有一个负责发送电子邮件的微服务。由于负载高,此服务被负载均衡器复制了 2 次。现在我们有 3 个电子邮件服务实例。当发布“sendMail”事件时,所有 3 个实例都在捕获该事件并为自己发送一封电子邮件。在一天结束时,正在发送 3 封电子邮件。

我的问题是,我可以配置一个允许我为这两种情况发布事件的云总线。我想对一个事件说“当一个听众抓住你时,消失”或“去找每个在外面等着的听众”。

例如;

微服务:A、B、C

由负载均衡器复制:A1、A2、A3、B1...

案例 1:我想为所有服务的实例发布一个事件。

案例 2:我想为服务 A 实例发布一个事件。

案例 3:我想为 A 的单个实例发布一个事件(不在乎哪个)。

我努力了; 为事件提供目的地,但所有实例都具有相同的总线名称,因为它们重复相同。如果我给出/知道单个实例总线名称,我不会使用它,因为那个 pod 可能会死掉。

活动发布;

applicationContext().publishEvent(
        new customEvent(
                this,  // Source
                busProperties().getId(),  // Origin Service
                null  // Destination Service (null: all)
        )
);

事件监听器;

@Component
public class Listener implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent event) {
        Foo();
    }
}

标签: javaspring-bootkubernetesspring-cloud

解决方案


我现在明白了,这是我之前发布的图片链接。我相信你已经知道了。这是一个常见问题,最好的方法是使用 redis 作为“阻塞”机制。由于消息队列向所有消费者异步发送请求,我们将不知道谁在接收和处理请求,但我们通过使用阻塞来确保它不会被所有人处理。在执行任何操作之前,请检查该块,如果它不存在,则处理请求。


推荐阅读