【发布时间】:2019-12-27 10:32:27
【问题描述】:
我正在开发一个项目,该项目具有多个事件驱动的微服务,并且还使用 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();
}
}
【问题讨论】:
-
这个bus你用什么? KubeMQ?
-
RabbitMQ 但我不想像 RabbitMQ 那样解决这个问题,我正在寻找框架级别的解决方案。
-
我明白了,您可以包含一个辅助消息确认主题,其中任何侦听器都会立即使用某个消息 ID 发布自己的侦听发生事件。虽然这是有风险的,但会有竞争条件,并且如果某些服务重新启动,它会继续读取过去的消息,您可能需要将这些读取的消息 id 存储在某个缓存中?替换所有经纪人中已经存在的功能变得非常混乱(我认为)
-
或者您可以将
listener模块提取为单独的single 服务,并将读取的消息提供给A、B、C也许是循环方式? -
我觉得必须有一个属性/配置来指定当单个侦听器使用它们时要删除的事件。那将很容易解决我的问题。但如果我找不到它,我不想要任何混乱的解决方案。我已经可以使用自动连接的 RabbitTemplate 将事件发布为 P2P,我想我可能会使用我不想要但也不混乱的解决方案。
标签: java spring-boot kubernetes spring-cloud