閒談軟體設計:NCC

更新 發佈閱讀 8 分鐘

現今的系統不論是 B to B、B to C 或是 B to B to C,通知都是不可少,不管是簡訊發送 OTP,還是發送臨時密碼的 email,或各式各樣的 push 通知,通知已不可少的環節,這也是為什麼在一開始系統架構設計時,早早把 ncc 規劃成一個獨立模組 (子系統)。

ncc 的全名是 Notification and Communication Center,乍看 Notification 和 Communication 意思好像很接近,但在語意上,Communication 泛指底層與外部系統的互動上,Nottification 則是系統與使用者的互動上。整體來說,ncc 子系統有幾個目的:

  • 提供簡單的抽象層,讓其它子系統表達「通知」的意圖即可,不用處理底層複雜的「通訊」細節
  • 管道式的處理流程,將不同通訊協定分開處理
  • 管理通知與訂閱
  • 提升通知的穩定性

接著就聊聊這四個目的是如何達成的。

意圖

很多時候,載入一個 sms 的套件或是 email 的套件,其「意圖」都是想要通知對方,sms 或是 email 的套件,只是實現這個意圖的手段,但為了這個手段卻讓商業邏輯與這些技術細節綁死,如果哪天換了個簡訊商 (別說這不可能,實際上我就遇過幾次),要換掉這些套件可不是件小工程。

那為 sms 提供一個抽象層,載入抽象層而不是某個特定簡訊商的套件,不就解決了?某種程度確實解決了一部分問題,但如果通訊的意圖更加複雜呢?例如 sms 如果失敗,換成 email?那這個轉換的細節也要放在商業邏輯中?

也許更好的方式,是讓商業邏輯層闡述其意圖即可,例如要發送簡訊,只要短短的一行:

notifications.notify(smsIntent(phone, "Your OTP is 985632."));

剩下的事就讓 ncc 去處理。下圖是簡化過後 ncc 意圖處理器的示意圖,可以發現到對商業邏輯層來說,不需要知道 SMS/eMail Provider (第三方的通訊商) 是誰,也不需要知道通知中心裡的事件是怎麼儲存的,當然也不用知道 WebSocket 或是 long polling 是怎麼處理的,只要表達意圖即可。

NCC Intent Processor

NCC Intent Processor

管道

從上圖可以看到,Facade 將意圖包裝後塞進 Message Queue,意圖處理器收到 Message 後,根據渠道 (Channel) 分送對應的管道 (Pipeline) 去處理,每個管道都是由一個 ChannelProcessor 處理意圖。

通常在處理這類呼叫第三方服務,都要面臨一個問題,失敗時要不要重試?如果要,要重試幾次?為了不要重複地寫這些邏輯,將重試也包裝成一個處理器 RetriableChannelProcessor,搭配 ChannelProcessorChain,將多個處理器串成一個 Pipeline,整個邏輯就清楚很多,可以任意組裝與調整。

NCC Intent Processor Classes

NCC Intent Processor Classes

從下面的範例就可以看到,sms 和 email 會最多重試 2 次,push 則是由三個處理器串起來,分別處理事件儲存、呼叫 FCM 和處理 fan out。任何一個渠道想增加邏輯,大多數情況下就是寫一個處理器,串到既有的管道即可。

訂閱

雖然 FCM (Firebase Cloud Messenging) 簡化了跨平台 (iOS/Android/Web) push notification 的處理,但 FCM 只處理了最末端的取得 token 與發送訊息,一個訂閱者有多個裝置,一個裝置可能切換不同的商家,一個商家可能有多個訂閱者,還要能檢視過去的通知等等,這些都是會根據自身的服務有不同的管理方式。

在既有已知的需求下 (時常提醒自己避免陷入 over design),要檢視過去的通知,都是以一個收件匣 (NotificationEventInbox) 為單位,同樣每則 push 通知的目的地也是一個收件匣,要訂閱,也是以收件匣為單位訂閱,一個訂閱可以有多個裝置並對應到一個 token,每個訂閱會管理最後讀取的事件,可以跨裝置處理未讀的數量。

Notification Event & Inbox

Notification Event & Inbox

穩定性

一個穩定的子系統是由多個不同面相組合起來的,像前面提到的重試也是一種面向,但只靠重試是不夠的,在雲端的環境,一個 pod 可能因為 crash 重啟,也可能因為升版重啟,那重啟的過程中,當有意圖要通知時怎麼辦?

這就是 Facade 和處理器之間用 Message Queue 的原因了,發送意圖時,不需要等待處理器是 ready 的狀態,只要確保意圖被送進 Message Queue 即可,那 Message Queue 會重啟嗎?當然可能會,因此這個部分就不是自架的服務,直接使用平台代管的 Message Queue 服務,平台代管服務通常會處理這些重啟中的請求,雖然不是滿分的答案,但依舊是可行的方案。

未來的擴充可能

目前,ncc 子系統運作十分良好,但這是在還沒有巨大壓力下的表現,依照過去的經驗,當使用者人數每成長一個量級 (10x),通訊相關的系統通常都需要一定程度的優化,在可預期的未來,ncc 應該會迎來幾個擴充和優化:

  • 平行化:當意圖的數量增加,為了更高的即時性,平行化是有必較的,在目前的架構下,平行化可以是內部透過 thread pool 完成,也可以是外部增加 pod 數量來完成。
  • 客製與多國語系:目前 push 通知的多國語系是交由裝置端處理,但如果通知的內容允許商家客製化後,就必須將多國語系的處理移回處理器內部 (多串一級多國語系處理的 Processor),並且提供客製訊息的管理。
  • 國際化:目前簡訊商只有串一家第三方服務,而這個服務商也只能發送台灣的門號,當業務拓展到其他國家時,就需要找第二個甚至第三個服務商,這時就需要根據國碼進行服務商的切換,甚至要有退路 (fallback) 機制,當某一個服務商失敗時,能切換到另一個服務商 (一樣,多串一級 Processor 處理分派,再串一級 Processor 處理 fallback)。
  • 狀態更新:現在多數的情況下,意圖的發送都是非同步,不會等待結果,NotificationIntent 本身更是一個 immutable value object,要知道處理的過程,都是靠查詢日誌來完成,之後如果要新增狀態的紀錄,或是將結果更新回商業邏輯層,都可以用新增 Processor 的方式處理。

小節

初期投資在 ncc 的架構,從構思到實作,前前後後大概一個禮拜不到,但這項投資在後面其實節省了許多時間,中間有些小補小修,但個人認為是一項十分值得的投資,更重要的是沒有過度投資,在未來擴充的那些項目,通通都沒有動工,因為目前不需要,等到需要時再進行即可。至於,這個設計適不適用在其他系統,建議還是個案討論會比較合適。



留言
avatar-img
留言分享你的想法!
avatar-img
Spirit的沙龍
56會員
110內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
2025/12/13
本文深入探討了 UUID 的演進,介紹了 UUID v6 和 v7 相較於舊版本在時間排序上的顯著提升,以及 ULID 作為另一種優化 ID 設計的替代方案。技術是不斷進化的,定期檢視是必要的。
Thumbnail
2025/12/13
本文深入探討了 UUID 的演進,介紹了 UUID v6 和 v7 相較於舊版本在時間排序上的顯著提升,以及 ULID 作為另一種優化 ID 設計的替代方案。技術是不斷進化的,定期檢視是必要的。
Thumbnail
2025/11/22
分享自身團隊在 Cloudflare 當機時,如何透過事先規劃的備援機制,在極短時間內將服務切換至 GCP Cloud DNS 並恢復正常運作的經驗。文章深入探討備援設計的複雜性,涵蓋成本、同步、複雜度及演練等面向,並總結事後檢討,強調建置外部監控系統和自動化 SSL 憑證更新的重要性。
Thumbnail
2025/11/22
分享自身團隊在 Cloudflare 當機時,如何透過事先規劃的備援機制,在極短時間內將服務切換至 GCP Cloud DNS 並恢復正常運作的經驗。文章深入探討備援設計的複雜性,涵蓋成本、同步、複雜度及演練等面向,並總結事後檢討,強調建置外部監控系統和自動化 SSL 憑證更新的重要性。
Thumbnail
2025/06/29
本文探討後端 API 安全驗證機制,說明如何基於請求憑證進行身家調查,確保只有授權使用者才能存取資源。文中詳細闡述了資料採信原則、角色來源、組織層級的設計考量,並介紹簡單的實作範例,以確保系統安全。
Thumbnail
2025/06/29
本文探討後端 API 安全驗證機制,說明如何基於請求憑證進行身家調查,確保只有授權使用者才能存取資源。文中詳細闡述了資料採信原則、角色來源、組織層級的設計考量,並介紹簡單的實作範例,以確保系統安全。
Thumbnail
看更多
你可能也想看
Thumbnail
以前只有用過 iMove 剪過自己的結婚成長影片,就是用一些照片幻燈片搭配感動的音樂,雖然技術力薄弱,但在婚禮現場播放時,可能只有我自己看得懂那段影片的故事,我居然哭到淚流不止啊!婚攝大哥也很敬業,就把那個瞬間捕捉下來了。 後來也是因為工作上的需求,有嘗試過有各種行動剪輯軟體來完成一些小短片,所以還
Thumbnail
以前只有用過 iMove 剪過自己的結婚成長影片,就是用一些照片幻燈片搭配感動的音樂,雖然技術力薄弱,但在婚禮現場播放時,可能只有我自己看得懂那段影片的故事,我居然哭到淚流不止啊!婚攝大哥也很敬業,就把那個瞬間捕捉下來了。 後來也是因為工作上的需求,有嘗試過有各種行動剪輯軟體來完成一些小短片,所以還
Thumbnail
倘若你有參加先前在 Matters Lab Discord 辦的資安課,以及我設計的資安小問答,就會知道以資訊安全來說,「傳統電腦」確實是比「智慧型手機」還更危險的(當然前提是都有在更新作業系統)。關於這部分的討論,就不再贅述。
Thumbnail
倘若你有參加先前在 Matters Lab Discord 辦的資安課,以及我設計的資安小問答,就會知道以資訊安全來說,「傳統電腦」確實是比「智慧型手機」還更危險的(當然前提是都有在更新作業系統)。關於這部分的討論,就不再贅述。
Thumbnail
你是否曾因視訊開會沒人發言而感到困擾,又或是想要同時可以共享兩個以上的螢幕?不管是 EP0.2 提過的 Zoom、Webex,抑或微軟的 Teams 和谷歌的 Meet 皆為付費軟體,均需綁定帳號及一連串設定;而本篇文章要帶你了解的是毋須註冊、用電腦也不用下載軟體的免費工具 Jitsi Meet。
Thumbnail
你是否曾因視訊開會沒人發言而感到困擾,又或是想要同時可以共享兩個以上的螢幕?不管是 EP0.2 提過的 Zoom、Webex,抑或微軟的 Teams 和谷歌的 Meet 皆為付費軟體,均需綁定帳號及一連串設定;而本篇文章要帶你了解的是毋須註冊、用電腦也不用下載軟體的免費工具 Jitsi Meet。
Thumbnail
科技成長股有很多細分的板塊,像是SaaS軟體股、金融科技股,電商股、廣告科技股、社交媒體股,等等。最近這一輪跌市看下來,即使整體都比較慘,但當中還是以SaaS軟體股相對抗跌,算是科技成長股當中的「疾風勁草」。
Thumbnail
科技成長股有很多細分的板塊,像是SaaS軟體股、金融科技股,電商股、廣告科技股、社交媒體股,等等。最近這一輪跌市看下來,即使整體都比較慘,但當中還是以SaaS軟體股相對抗跌,算是科技成長股當中的「疾風勁草」。
Thumbnail
今天是除夕,先跟大家說一聲新年快樂!回到美股,我們追蹤股票的財報季也即將展開了,如果是最近才訂閱的讀者可能不清楚,這裡先簡單說明幾句本專欄運作方式......
Thumbnail
今天是除夕,先跟大家說一聲新年快樂!回到美股,我們追蹤股票的財報季也即將展開了,如果是最近才訂閱的讀者可能不清楚,這裡先簡單說明幾句本專欄運作方式......
Thumbnail
最近我們在TG付費群組就日後如何可以更好地讓投資組合更具抗風險性,有過一些討論。我自己最近也在檢討這個。在去年3月那波之後,我自己改變了以往都100%成長股的做法,從去年下半年開始汰弱留強持股的時候,慢慢挪出了一定的現金比例......
Thumbnail
最近我們在TG付費群組就日後如何可以更好地讓投資組合更具抗風險性,有過一些討論。我自己最近也在檢討這個。在去年3月那波之後,我自己改變了以往都100%成長股的做法,從去年下半年開始汰弱留強持股的時候,慢慢挪出了一定的現金比例......
Thumbnail
從去年11月以來,科技成長股板塊已經調整了一段時間,下跌幅度之深應該是自2020年疫情初次爆發以來最大。至於為甚麼大跌,我前面很多篇文章都講了,這裡就不贅述;過去一段時間,也多次提到我個人並不看好今年上半年科技成長股的表現,雖然真的也沒料到跌幅會如此之深,但操作上已經保守好一陣子......
Thumbnail
從去年11月以來,科技成長股板塊已經調整了一段時間,下跌幅度之深應該是自2020年疫情初次爆發以來最大。至於為甚麼大跌,我前面很多篇文章都講了,這裡就不贅述;過去一段時間,也多次提到我個人並不看好今年上半年科技成長股的表現,雖然真的也沒料到跌幅會如此之深,但操作上已經保守好一陣子......
Thumbnail
這個「軟體股板塊歷史估值變化行情表」是我一個新的追蹤嘗試,背後的思考理路可以詳細參考我另一篇談成長股估值的文章:〈【投資心法】科技成長股如何估值?從過去一年的經驗,談談估值的幾個層次〉,希望從整體行情看板塊大致的歷史估值變化。
Thumbnail
這個「軟體股板塊歷史估值變化行情表」是我一個新的追蹤嘗試,背後的思考理路可以詳細參考我另一篇談成長股估值的文章:〈【投資心法】科技成長股如何估值?從過去一年的經驗,談談估值的幾個層次〉,希望從整體行情看板塊大致的歷史估值變化。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News