簡體   English   中英

將事件發布到單個微服務實例

[英]Publishing an Event to a Single Microservice Instance

我正在一個項目中,該項目具有多個事件驅動的微服務,並且還使用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();
    }
}

我現在了解得更好,這是我之前發布的圖像鏈接 我確定您已經知道了。 這是一個常見問題,最好的方法是使用Redis作為“ 阻止 ”機制。 由於消息隊列正在異步向所有使用者發送請求,因此我們將不知道誰在接收和處理該請求,但是通過使用阻塞,我們確保所有人不會對其進行處理。 在執行任何操作之前,請檢查該塊,如果不存在,請處理該請求。

我相信可以通過設置consumerGroupId來解決。 您的應用程序的每個實例(電子郵件服務的每個微服務)都需要具有唯一的groupId,以便rabbitmq將請求發送到那些可用的唯一組中的任何一個。

下面是它的工作原理

我已經發現並實施了部分解決方案,將Spring Cloud Stream與Spring Cloud Bus一起使用。 我將Cloud Stream與單個事件(第一個示例的sendmail事件)的自定義隊列和組一起使用。 當我通過Cloud Stream發送消息時,如果微服務的多個實例正在偵聽消息,它們將像這樣一個接一個地接收消息:

正在發送消息:M1,M2,M3

監聽一個微服務實例:A1,A2

使用Cloud Bus:

A1接收M1,M2,M3

A2接收M1,M2,M3

使用Cloud Stream(定義了自定義組):

A1收到M1,M3

A2收到M2

實施: https//www.baeldung.com/spring-cloud-stream

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM