我有一個訊息生產者,將訊息發送{"user_id": 1, "message": "Ciao"}到 SQS 佇列。
我有一個 Websocket API 的三個實體,它們的名字是 A、B 和 C。
假設有五個用戶連接到該 API,他們的 ID 為 1、2、3、4 和 5。
每個用戶都連接到 API,我的平衡器(sticky ofc)使客戶端以這種方式連接到 API:
A: 1, 3
B: 5
C: 2, 4
現在,Websocket API 是上面提到的 SQS 佇列的使用者。
當我為用戶 1 排入一條訊息時,任何消費者都可以先將其出列,假設 C 是這樣。
實體C無法對 user_id 1 的訊息執行任何操作。A確實持有與該用戶的實際連接。
在我看來,這應該是這樣的:所有三個 API 實體都會收到任何訊息。
- C 將讀取它,并將其留在佇列中
- B 將讀取它,并將其留在佇列中
- A 將讀取它,處理它并將其從佇列中洗掉
我的問題是:
上述作業流程是否可以通過 SQS 實施?
是否可以從佇列中讀取訊息并將其留在那里?或者,如果當前消費者無法處理,我是否必須將其出隊并重新入隊?
uj5u.com熱心網友回復:
只有 SQS 是可行的(但需要在消費者中定制代碼)。
示例:SQS 根據消費者發送的確認洗掉訊息。如果消費者發送確認,SQS 將洗掉該條目。因此,一種設計方法是:
a) 消費訊息 b) 檢查它是否是所需的訊息 c) 如果是,則向 SQS 發送一個 ACK??,SQS 將洗掉該條目 d) 如果該訊息不是所需的訊息,則不發送并確認,SQS 將保持記錄
其他方法:
你可以結合 SQS 和 SNS 來實作它。
您可以為 3 個 Websocket API 設定 3 個單獨的佇列,例如SQS_A, SQS_B, SQS_C. 你可以讓一個 SNS 話題說,MyTopic. 然后,您可以根據訂閱過濾使 Queue 訂閱 SNS 主題。
例子,
SQS_A如果事件過濾器user_id 1 and 3在其中,則將訂閱 SNS 主題。SQS_B如果事件過濾器user_id 5在其中,則將訂閱 SNS 主題。SQS_C如果事件過濾器user_id 2在其中,則將訂閱 SNS 主題。
SQS_A 的事件過濾如下所示:
{
"EventType": [
1,
3"
]
}
所以...現在當發布者發布訊息時,它會將訊息連同事件型別一起發布到 SNS 主題。
例子:
sns.PublishInput{
Message: msg,
TopicArn: topic,
MessageAttributes: {
EventType: {
DataType: "String",
StringValue: <listOfUserId>
}
}
}
現在,SNS 只會將此訊息發送到SQS_ASQS 的其余部分,而不會發送到SQS 的其余部分。因此,只有 Websocket A 會使用該訊息。
更多:
在您的用例中,
[Mesage for user 1/3]-> SNS -> SQS for A -> Websocket A only gets messages for user 1/3
[Mesage for user 5]-> SNS -> SQS for B ->Websocket A only gets messages for user 5
請注意,兩種情況下的 SNS 主題保持不變。但是訂閱者會過濾訊息,您將擁有多個 SQS 佇列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/362235.html
