訊息通知(Notification)系統最佳化

帶你聊技術發表於2023-12-19


來源:JavaEdge


5 收集聯絡資訊流程

為傳送通知,需收集各種資訊如移動裝置令牌、email、phone和第三方通道資訊。

訊息通知(Notification)系統最佳化

用於儲存聯絡資訊的簡化的資料庫表模式。它是個帶有電子郵件、電話、裝置令牌和外部通道的單個NoSQL DynamoDB表。Contacts table schema:

device_tokens 應以 JSON 格式儲存。示例:

[
 {
   "deviceToken""[裝置令牌UUID]",
   "platform""apns"
 },
 {
   "deviceToken""[裝置令牌UUID]",
   "platform""fcm"
 }
]

external_channels 欄位

[
  {
      "platform""slack",
      "url""[通道的唯一URL]",
      "status"true
  },
  {
      "platform""another-service",
      "url""...",
      "status"false
  }
]

使用者可擁有多個裝置、第三方通道,表示可將推送通知傳送到使用者的所有裝置。

6 通知傳送和接收流程

初始設計的通知系統:

訊息通知(Notification)系統最佳化

圖從左到右:

外部生產者 1~N — 代表希望透過通知系統提供的API傳送通知的不同服務。如結算服務傳送簡訊提醒客戶付款到期,或者購物網站的交付訊息到他們的客戶。

API閘道器 將為生產者提供API介面,並將請求正確地路由到通知服務(Lambda)。

通知服務 類似後端服務,功能如下:

  • 執行基本驗證,以驗證電子郵件、電話號碼、裝置令牌等。
  • 查詢資料庫以獲取生成通知事件所需的資料。
  • 將通知資料推送到事件匯流排以進行並行處理。

聯絡人資料庫 — 儲存有關使用者、聯絡資訊、設定等資料的DynamoDB表。

EventBridge,AWS服務,將其用作事件匯流排。還需定義事件規則以正確將事件路由到佇列。

這是通知事件的示例。每個 detail-type 將針對一個通知型別。因此,SQS佇列根據屬性模式過濾事件。

{
  "id""<required::uuid>",
  "source""payment_request_event",
  "detail-type": ["payment_notification_sms"],
  "resources": ["payments"],
  "detail": {...}
  "time""<required>",
  "region""<required>",
  "account""<required>"
}

訊息佇列 — 它們用於消除元件之間的依賴關係。SQS佇列在需要傳送大量通知時充當緩衝區。每種通知事件型別都分配到一個獨立的訊息佇列,以便一個傳送服務的中斷不會影響其他通知型別。

Worker — 從SQS佇列輪詢通知事件並將其傳送到相應的服務的Lambda服務列表。

SNS或第三方服務 — 這些服務負責將通知傳遞給消費者。在與第三方服務整合時,我們需要關注可擴充套件性和高可用性。可擴充套件性的一個很好的例子是一個靈活的系統,可以輕鬆切換第三方服務的開/關。另一個重要考慮因素是第三方服務可能在某種程度上不可用,然後我們應該能夠切換到另一個服務,並儘量減小對業務的影響。

7 最佳化

在高階設計中,我們討論了通知系統的三個主要部分:不同型別的通知、收集聯絡資訊流程和通知傳送/接收流程。關鍵是:

  • 事件和推送通知中的安全性
  • 通知模板和設定
  • 可靠性和彈性
  • 重試機制
  • 速率限制
  • 監視佇列中的通知和事件跟蹤

事件和推送通知的安全性

  • 在儲存敏感資料的情況下,我們應該啟用DynamoDB的資料保護,如靜態加密,並整合AWS Key Management Service(AWS KMS)以管理用於加密表的加密金鑰。並使用IAM角色對DynamoDB的訪問進行身份驗證。
  • 在訪問資源方面實施最小許可權原則
  • 透過使用SSL/TLS與AWS資源通訊,啟用EventBridge的資料保護,以在傳輸中進行加密。建議使用TLS 1.3。
  • 對於iOS和Android應用,appKey和appSecret用於保護推送通知API。只有經過身份驗證或經過驗證的客戶端才允許使用API傳送推送通知。這些憑據應透過Secret Manager或Parameter Store儲存和加密。

通知模板和設定

  • 我們應該為相同通知型別建立一個通知模板,其遵循相似的格式。它可以被重用,並避免從頭開始構建每個通知內容。
  • 通知模板是預格式化的通知內容,透過自定義引數、跟蹤連結

等建立唯一的通知。我們可以將這些通知模板儲存在帶有定義字首的S3桶中。

  • 為了為使用者提供對通知設定的細粒度控制,我們可以將其儲存在單獨的通知設定表中。在向使用者傳送任何通知之前,我們首先檢查使用者是否願意接收這種型別的通知。

可靠性和彈性

  • 防止資料丟失 — 通知系統中最重要的非功能性要求之一是不能丟失資料。通知可能會延遲或重新排序,但不應該丟失。為了滿足此要求,通知系統將通知資料持久儲存在另一個日誌表中,並實施重試機制。
  • 接收一條通知確切地一次嗎? — 不,不可以。根據第三方服務提供商的SLA,儘管通知大多數時候確切地傳遞一次,但分散式性質可能導致重複的通知。我們可以減少重複的發生,然後引入去重機制並小心處理故障。
  • 這是一個簡化的邏輯:當通知事件首次到來時,我們透過檢查 eventId 來檢視它是否以前傳遞過。如果之前成功傳遞,則將其丟棄。否則,我們將傳送通知。
  • 彈性基礎設施 — 我們應該考慮在多個可用區部署,您可以設計和操作可以在可用區之間自動故障轉移而不中斷的應用程式和資料庫。可用區比傳統的單一或多資料中心基礎設施更具高可用性、容錯性和可擴充套件性。

重試機制

  • 當SNS/第三方服務無法傳送通知時,通知將被新增到死信佇列進行重試。如果問題仍然存在,將向負責的開發人員傳送警報。

速率限制

  • 我們應該考慮禮貌地傳送通知。為了避免向使用者傳送過多通知,透過使用SQS並限制使用者在一段時間內可以接收的通知數量,我們可以提高通知系統的禮貌度。

監視佇列中的通知和事件跟蹤

  • 我們應該使用AWS CloudWatch指標監視通知系統。要監視的關鍵指標是EventBirdge中的事件總數和排隊通知的總數。如果這兩個指標很大,那麼通知事件沒有被工作人員快速處理。這意味著我們應該擴充套件,需要更多的工作人員。
  • 事件跟蹤 — 一些重要的自定義指標,如開放率、點選率和參與度,對於理解客戶行為很重要。我們應該為事件分配狀態:已建立 → 待處理 → 已傳送 → 已開啟 → 已點選或錯誤、已退訂。將事件狀態整合到通知系統中,我們可以追蹤通知事件。

更新的高階架構

訊息通知(Notification)系統最佳化

帶有AWS的最佳化通知系統

8 結論

文章強調了通知在讓我們瞭解關鍵資訊方面的不可或缺性。旨在闡明可擴充套件、高可用和可靠的通知系統的藍圖,該系統可適應各種通知型別,包括移動推送通知、簡訊、電子郵件和第三方應用通知。

為實現目標,我選擇基於事件的架構,利用EventBridge和SQS佇列解耦系統元件。

設計廣泛使用AWS服務,採用無伺服器框架,這種選擇不僅確保了效率,而且還將定價和運營成本降到了最低。

該設計遵循了十二要素應用的原則,將支援服務視為附加資源,將配置儲存在環境中,並將日誌視為事件流,其中還考慮了其他一些因素。

來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024922/viewspace-3000556/,如需轉載,請註明出處,否則將追究法律責任。

相關文章