啊,業(yè)務層是否也需要服務化?
《互聯(lián)網(wǎng)分層架構的本質(zhì)》簡述了兩個觀點:
- 互聯(lián)網(wǎng)分層架構的本質(zhì),是數(shù)據(jù)的移動
- 互聯(lián)網(wǎng)分層架構演進的核心原則:是讓上游更高效的獲取與處理數(shù)據(jù),讓下游能屏蔽數(shù)據(jù)的獲取細節(jié)
《分層架構:什么時候抽象DAO層,什么時候抽象數(shù)據(jù)服務層》中的觀點是:
- 當手寫代碼從DB中獲取數(shù)據(jù),成為通用痛點的時候,就應該抽象出DAO層,簡化數(shù)據(jù)獲取過程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復雜性
- 當業(yè)務越來越復雜,垂直拆分的系統(tǒng)越來越多,數(shù)據(jù)庫實施了水平切分,數(shù)據(jù)層實施了緩存加速之后,底層數(shù)據(jù)獲取復雜性成為通用痛點的時候,就應該抽象出數(shù)據(jù)服務層,簡化數(shù)據(jù)獲取過程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復雜性
文本將要解答的問題是:
- 基礎數(shù)據(jù)的訪問需要服務化,業(yè)務層是否需要服務化
- 如果需要服務化,什么時候服務化
基礎數(shù)據(jù)的訪問服務化之后,一個業(yè)務系統(tǒng)的后端架構如上:
- web-server通過RPC接口,從基礎數(shù)據(jù)service獲取數(shù)據(jù)
- 基礎數(shù)據(jù)service通過DAO,從db/cache獲取數(shù)據(jù)
- db/cache存儲數(shù)據(jù)
隨著時間的推移,系統(tǒng)架構并不會一成不變:
- 隨著業(yè)務越來越復雜,業(yè)務會不斷進行垂直拆分
- 隨著數(shù)據(jù)越來越復雜,基礎數(shù)據(jù)service也會越來越多
于是系統(tǒng)架構變成了上圖這個樣子,業(yè)務垂直拆分,有若干個基礎數(shù)據(jù)服務:
- 垂直業(yè)務要通過多個RPC接口訪問不同的基礎數(shù)據(jù)service,service共有是服務化的特征
- 每個基礎數(shù)據(jù)service訪問自己的數(shù)據(jù)存儲,數(shù)據(jù)私有也是服務化的特征
這個架構圖中的依賴關系是不是看上去很別扭?
- 基礎數(shù)據(jù)service與存儲層之前連接關系很清晰
- 業(yè)務web-server層與基礎數(shù)據(jù)service層之間的連接關系錯綜復雜,變成了蜘蛛網(wǎng)
再舉一個更具體的例子,58同城列表頁web-server如何獲取底層的數(shù)據(jù)?
- 首先調(diào)用商業(yè)基礎service,獲取商業(yè)廣告帖子數(shù)據(jù),用于頂部置頂/精準的廣告帖子展示
- 再調(diào)用搜索基礎service,獲取自然搜索帖子數(shù)據(jù),用于中部自然搜索帖子展示
- 再調(diào)用推薦基礎service,獲取推薦帖子數(shù)據(jù),用于底部推薦帖子展示
- 再調(diào)用用戶基礎service,獲取用戶數(shù)據(jù),用于右側(cè)用戶信息展示
- …
如果只有一個列表頁這么寫還行,但如果有招聘、房產(chǎn)、二手、二手車、黃頁…等多個大部分是共性數(shù)據(jù),少部分是個性數(shù)據(jù)的列表頁,每次都這么獲取數(shù)據(jù),就略顯低效了,有大量冗余、重復、每次必寫的代碼。
特別的,不同業(yè)務上游列表頁都依賴于底層若干相同服務:
- 一旦一個服務RPC接口有稍許變化,所有上游的系統(tǒng)都需要升級修改
- 子系統(tǒng)之間很可能出現(xiàn)代碼拷貝
- 一旦拷貝代碼,出現(xiàn)一個bug,多個子系統(tǒng)都需要升級修改
如何讓數(shù)據(jù)的獲取更加高效快捷呢?
業(yè)務服務化,通用業(yè)務服務層的抽象勢在必行。
通過抽象通用業(yè)務服務層,例如58同城“通用列表服務”:
- web-server層,可以通過RPC接口,像調(diào)用本地函數(shù)一樣,調(diào)用通用業(yè)務service,一次性獲取所有通用數(shù)據(jù)
- 通用業(yè)務service,也可以通過多次調(diào)用基礎數(shù)據(jù)service提供的RPC接口,分別獲取數(shù)據(jù),底層數(shù)據(jù)獲取的復雜性,全都屏蔽在了此處
是不是連接關系也看起來更清晰?
這樣的好處是:
- 復雜的從基礎服務獲取數(shù)據(jù)代碼,只有在通用業(yè)務service處寫了一次,沒有代碼拷貝
- 底層基礎數(shù)據(jù)service接口發(fā)生變化,只有通用業(yè)務service一處需要升級修改
- 如果有bug,不管是底層基礎數(shù)據(jù)service的bug,還是通用業(yè)務service的bug,都只有一處需要升級修改
- 業(yè)務web-server獲取數(shù)據(jù)更便捷,獲取所有數(shù)據(jù),只需一個RPC接口調(diào)用
結論:
當業(yè)務越來越復雜,垂直拆分的系統(tǒng)越來越多,基礎數(shù)據(jù)服務越來越多,底層數(shù)據(jù)獲取復雜性成為通用痛點的時候,就應該抽象出通用業(yè)務服務,簡化數(shù)據(jù)獲取過程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復雜性。
最后再強調(diào)兩點:
- 是否需要抽象通用業(yè)務服務,和業(yè)務復雜性,以及業(yè)務發(fā)展階段有關,不可一概而論
- 需要抽象什么通用業(yè)務服務,和具體業(yè)務相關
任何脫離業(yè)務的架構設計,都是耍流氓。
【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】