服務(wù)架構(gòu):Web-Queue-Worker架構(gòu)
- 這種架構(gòu)的核心組件包含:
- 一個Web前端,用戶可以通過這里發(fā)送請求
- 一個worker服務(wù),它可以執(zhí)行資源密集型任務(wù)、耗時的工作流或批處理作業(yè)。
Web前端和worker服務(wù)通過一個消息隊列進(jìn)行通信。
這個架構(gòu)中還包含其它一些組件:
- 一個/多個數(shù)據(jù)庫
- KV Cache,用來降低數(shù)據(jù)庫的負(fù)載
- CDN系統(tǒng),提供靜態(tài)資源的訪問加速
- 遠(yuǎn)程服務(wù),比如email或消息發(fā)送服務(wù),通常是第三方的服務(wù)
- 身份認(rèn)證服務(wù),比如Google Oauth登錄服務(wù)
Web前端和worker服務(wù)都是無狀態(tài)的。作業(yè)的會話狀態(tài)通常存儲在分布式存儲里(比如Redis集群)。worker通過異步的方式處理耗時的作業(yè),我們通常使用消息隊列來觸發(fā)作業(yè)的創(chuàng)建和執(zhí)行,或者通過一個定時任務(wù)調(diào)度批處理任務(wù)。worker并不是必須的,如果沒有耗時的操作,就不需要它。
前端除了頁面的部分,也可以提供web API(BFF層)。在client端,我們可以通過一個單頁應(yīng)用觸發(fā)ajax請求,或者使用原生的APP去觸發(fā)。
應(yīng)用場景
Web-Queue-worker架構(gòu)在云服務(wù)中很常見,比如函數(shù)計算服務(wù)(FAAS)。這類服務(wù)通常會提供 HTTP API 或 RPC API,同時支持消費Kafka來的流式消息。目前流行的低代碼也是由此衍生出來的。
該架構(gòu)適用于以下的場景:
- 應(yīng)用的業(yè)務(wù)領(lǐng)域/場景比較簡單
- 應(yīng)用包含了一些耗時的工作流或批處理任務(wù);
- 想要低成本地接入現(xiàn)有的服務(wù),而不是從Infra開始搭建
架構(gòu)優(yōu)勢
- 架構(gòu)簡單易懂;
- 部署和管理很簡單;
- 服務(wù)職能邊界清晰;
- 前端和worker是解耦的,消息隊列使用現(xiàn)成的技術(shù)即可;
- 前端和worker可以獨立進(jìn)行擴容;
有哪些挑戰(zhàn)
- 如果設(shè)計不合理,前端和worker都可能融入太多的邏輯,變得越來越重。后期演變成單體架構(gòu)后,很難維護(hù)和升級;
- 如果前端和worker共享了一些數(shù)據(jù)結(jié)構(gòu)或代碼,可能會有隱藏的依賴;
最佳實踐
- 暴露給client的API必須清晰明了,經(jīng)過良好的設(shè)計;對于HTTP請求,可以遵循REST協(xié)議;
- 對于工作負(fù)載的變化,啟動自動擴縮容;云平臺和K8s都提供了監(jiān)控實例CPU/內(nèi)存自動擴縮容的能力;
- 對于半靜態(tài)的數(shù)據(jù),使用緩存進(jìn)行加速訪問;比如memcached/memory cache等;
- 使用CDN對靜態(tài)資源進(jìn)行緩存加速;
- 根據(jù)需求使用混合持久化方案。比如關(guān)系數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫混合使用,比如KV存儲、文檔數(shù)據(jù)庫、搜索數(shù)據(jù)庫、時序數(shù)據(jù)庫、列式存儲數(shù)據(jù)庫、圖數(shù)據(jù)庫等。數(shù)據(jù)庫之間,可以采用最終一致性方案進(jìn)行數(shù)據(jù)同步;
- 對數(shù)據(jù)進(jìn)行分區(qū),分區(qū)可以更好地支持?jǐn)U容,減少競爭讀寫問題,提升訪問性能。