iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0

前面幾天,PokeThreads 的架構已經慢慢演化成分散式系統,不過所有功能都還圍繞在「發文、讀文」上。

只有這麼簡單的功能,實在太像古早時期的社群網站,今天要加入一個現代社群平台幾乎必備的功能:Notification(通知)

情境很簡單:Pikachu 發了一篇貼文,Charmander 看到之後按下 Like,Pikachu 應該要收到一則「Charmander liked your post」的通知。

最簡單的 Notification

先從最直白的做法開始:Notification 就是一筆寫進 Database 的資料,使用者打開通知頁面時,Server 再把這些資料撈出來回傳。

先定義 Notifications 這張表:

  • Notification
    • id:BIGINT(Primary Key)
    • recipient_id:BIGINT(Foreign Key → User.id,誰收到這則通知)
    • actor_id:BIGINT(Foreign Key → User.id,誰觸發了這個事件)
    • type:VARCHAR(20)(通知類型,例如 LIKE
    • post_id:BIGINT(Foreign Key → Post.id,可為 NULL)
    • created_at:TIMESTAMP
    • is_read:BOOLEAN

一個 Like 觸發通知的流程大致如下:

Like 觸發通知的同步流程圖

寫進 Database 的資料看起來會是這樣:

recipient_id = Pikachu
actor_id     = Charmander
type         = LIKE
post_id      = 123
created_at   = ...
is_read      = false

之後 Pikachu 打開 PokeThreads,前端呼叫 GET /notifications,後端到 Database 撈出屬於他的通知回傳。

當系統還很小、通知類型也只有 LIKE 的時候,這個設計完全夠用。

規模變大之後的問題

假設現在通知類型不只 LIKE,還加入了 FOLLOWREPLYMENTION

一個簡單的使用者操作,背後要觸發的工作也跟著變多。原本單純的一支 API,開始要做越來越多事情,新問題也隨之而來。

問題一:API Latency 越來越高

假設:

  • Create Like 需要 10ms
  • Create Notification 需要 20ms
  • Update Counter 需要 10ms

如果這些步驟全部同步執行,一次 Like 就要花 40ms 才能回應,而這還沒算上實際系統裡更多的 DB Query 與網路延遲。

問題二:Notification 失敗會拖累原本的操作

假設 Charmander 對 Pikachu 的貼文按讚,Create Like 成功了,但緊接著 Create Notification 失敗。

如果這時候整支 API 回傳失敗,Charmander 可能會誤以為自己的 Like 根本沒生效;但如果反過來讓 API 回傳成功、卻放任 Notification 沒有真的建立,Pikachu 就永遠收不到這則通知。

問題的根源在於:我們把兩件重要程度完全不同的工作,硬綁在同一個同步流程裡。

同步處理 vs 非同步處理

現在的做法是完全同步:

Charmander -> Like API -> Create Like -> Create Notification -> Response

如果之後把 Create Notification 從這條流程裡拆出去,讓它在這次 Request 結束後再慢慢完成,這就是非同步處理

小結

今天做出了 Notification 的第一個版本:一個 Table、一支寫入、一支查詢,在系統規模小的時候完全合理。

但隨著通知類型變多,同步流程的缺點也跟著浮現,API 越來越慢,而且一個不重要的步驟(例如建立通知)出錯,反而可能拖累使用者真正在乎的操作(例如按讚有沒有成功)。

下一篇要處理的,就是怎麼把這些「不需要使用者立刻等待結果」的工作,從主流程中拆出去。


上一篇
Day 10 Media Pipeline 上傳一張圖片,中間發生了什麼事?
系列文
系統設計就像九頭蛇:打造社群網站的 30 天11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言