前幾天在 HN 看到的,為現在的 Real-time web app 提出一種可能的架構實作法。
client 藉由 websocket 連結 communication layer,把請求寫入 message queue 中,再交由 consumer 處裡 queue 裡的任務。因為是 websocket 所以可以雙向溝通,consumer 處裡完後再把訊息寫到 queue,由 communication layer 回傳結果到 client。
如果有寫過 messaging 之類的 web app,那架構上多半會摻了類似的概念。
不過這種全靠 persist socket 的做法有很多缺點:
你要處理訊息接受次數可能是 0, 1, 和多次。本來 http 的傳統架構是 request-response,只有失敗和成功兩種結果。如果是 message queue 的話,就有可能因為斷線重連而變空炮彈 (server 有回你但你沒收到),光是要解決這問題就很煩了。然後這問題接下來衍生更難的困境
即然 client (browser) 會掉訊息,那麼 server 的行為就需要變成 "最少送成功一次"。這意味有很多情況是同個 message 會重覆發 (在斷線頻發時),client side 的程式要能處理這種狀況。想也知道要花多少精力維護這種狀況 (every operation must be idempotent)
這問題在 mobile web 上更是嚴重,persist socket 一天斷個十幾次 (3G/4G 隨便斷線的)。在桌機 browser 沒看到的問題通通跑出來了,寫到最後你會想放棄的。
這篇作者提的架構是適合 Single Page App (SAP)。但在 mobile web 上這架構不是很討好,client side js render 在手機上其實很慢,最後都要回歸 server 來 render,而且也不是所有服務都適合 SAP。
最後用 websocket 的省頻寬,省連線數什麼的,這問題在 http2 下已經解決,所以這優點已經消失。