互聯網架構,究竟爲啥要作服務化?

最近留言問「微服務」的朋友頗多,找歷史文章又找不到,故從新優化發佈,但願你們有收穫,不要被「微服務大潮」誤導。nginx

「微服務架構」的話題很是之火,不少朋友都在小窗我,說怎麼作服務化?解答「怎麼作」以前,先得了解「爲何作」。
畫外音:作技術千萬不能是這種思路,「別人都在作,因此咱們也要搞」。程序員

並非全部的業務都適合「服務化」,互聯網高可用架構,到底爲何要服務化?web

服務化以前,高可用架構是什麼樣的?

在服務化以前,互聯網的典型高可用架構以下:
互聯網架構,究竟爲啥要作服務化?
(1)客戶端,APP,H5,小程序,PC瀏覽器;
(2)後端入口,高可用的反向代理nginx集羣;
(3)站點應用,高可用的web-server集羣;
(4)後端存儲,高可用db集羣;
互聯網架構,究竟爲啥要作服務化?數據庫

更典型的,web-server集羣經過DAO/ORM等技術來訪問數據庫。小程序

能夠看到,最初是沒有服務層的,此時架構會碰到什麼典型痛點呢?後端

架構痛點一:代碼處處拷貝

舉一個最多見的業務例子,用戶數據訪問,絕大部分公司都有一個數據庫存儲用戶數據,各個業務都有訪問用戶數據的需求。
互聯網架構,究竟爲啥要作服務化?
在有用戶服務以前,各個業務線都是本身經過DAO寫SQL訪問user庫來存取用戶數據,這無形中就致使了代碼的拷貝。瀏覽器

架構痛點二:複雜性擴散

隨着併發量的愈來愈高,用戶數據的訪問數據庫成了瓶頸,須要加入緩存來下降數據庫的讀壓力,因而架構中引入了緩存,若是沒有統一的服務層,互聯網架構,究竟爲啥要作服務化?各個業務線都須要關注緩存的引入致使的複雜性。緩存

對於寫請求,全部業務線都要升級代碼:
(1)先淘汰cache;
(2)再寫db;網絡

對於讀請求,全部業務線也都要升級代碼:
(1)先讀cache,命中則返回;
(2)沒命中則讀db;
(3)再把數據放入cache;架構

這個複雜性是典型的「業務無關」的複雜性,業務方須要被迫升級。

隨着數據量的愈來愈大,數據庫須要進行水平拆分,因而架構中又引入了分庫分表,若是沒有統一的服務層,各個業務線都須要關注分庫分表的引入致使的複雜性。
互聯網架構,究竟爲啥要作服務化?
這個複雜性也是典型的「業務無關」的複雜性,業務方須要被迫升級。

典型的耦合,還包括bug的修改,發現一個bug,多個地方都須要修改。

架構痛點三:庫的複用與耦合

服務化並非惟一的解決上述兩痛點的方法,抽象出統一的「庫」是最早容易想到的解決(1)代碼拷貝;(2)複雜性擴散;的方法。

抽象出一個user.so,負責整個用戶數據的存取,從而避免代碼的拷貝。至於複雜性,也只有user.so這一個地方須要關注了。

解決了舊的問題,會引入新的問題,庫的版本維護會致使業務線之間的耦合。

業務線A將user.so由版本1升級至版本2,若是不兼容業務線B的代碼,會致使B業務出現問題。

業務線A若是通知了業務線B升級,則是的業務線B會無端作一些「自身業務無關」的升級,很是鬱悶。固然,若是各個業務線都是拷貝了一份代碼則不存在這個問題。
畫外音:有時候拷貝代碼也是有好處的。

架構痛點四:SQL質量沒法保障,業務相互影響

互聯網架構,究竟爲啥要作服務化?
業務線經過DAO訪問數據庫,本質上SQL語句仍是各個業務線拼裝的,資深的工程師寫出高質量的SQL,經驗沒有這麼豐富的工程師可能會寫出一些低效的SQL。

假如業務線A寫了一個全表掃描的SQL,致使數據庫的CPU100%,影響的不僅是一個業務線,而是全部的業務線都會受影響。
畫外音:臨時工程序員要背鍋了。

架構痛點五:瘋狂的DB耦合

互聯網架構,究竟爲啥要作服務化?
業務線不僅訪問user數據,還會結合本身的業務訪問本身的數據。
畫外音:user_biz表,也是用uid作主鍵。

典型的,經過join數據表來實現各自業務線的一些業務邏輯。

業務線A的table-user與table-A耦合在了一塊兒,業務線B的table-user與table-B耦合在了一塊兒,業務線C的table-user與table-C耦合在了一塊兒,結果就是:table-user,table-A,table-B,table-C都耦合在了一塊兒。

隨着數據量的愈來愈大,業務線ABC的數據庫是沒法垂直拆分開的,必須使用一個大庫(瘋了,一個大庫300多個業務表 =_=)。

架構痛點六:…

服務化後,高可用架構如何?

互聯網高可用分層架構演進的過程當中,引入了「服務層」。
互聯網架構,究竟爲啥要作服務化?
以上文中的用戶業務爲例,引入了高可用user-service,對業務線響應所用用戶數據的存取。

引入服務層有什麼好處,到底解決什麼問題呢?

好處一:調用方爽

有服務層以前,業務方訪問用戶數據,須要經過DAO拼裝SQL訪問。

有服務層以後,業務方經過RPC訪問用戶數據,就像調用一個本地函數同樣,很是之爽:
User = UserService::GetUserById(uid);
傳入一個uid,獲得一個User實體,就像調用本地函數同樣,不須要關心序列化,網絡傳輸,後端執行,網絡傳輸,範序列化等複雜性。

好處二:複用性,防止代碼拷貝

全部user數據的存取,都經過user-service來進行,代碼只此一份,不存在拷貝。

升級一處升級,bug修改一處修改。

好處三:專一性,屏蔽底層複雜度

互聯網架構,究竟爲啥要作服務化?
在沒有服務層以前,全部業務線都須要關注緩存、分庫分表這些細節。
互聯網架構,究竟爲啥要作服務化?

在有了服務層以後,只有服務層須要專一關注底層的複雜性了,向上遊屏蔽了細節。

好處四:SQL質量獲得保障

互聯網架構,究竟爲啥要作服務化?
原來是業務向上遊直接拼接SQL訪問數據庫。
互聯網架構,究竟爲啥要作服務化?

有了服務層以後,全部的SQL都是服務層提供的,業務線不能再隨心所欲了。底層服務對於穩定性的要求更好的話,能夠由更資深的工程師維護,而不是像原來SQL難以收口,難以控制。

好處五:數據庫解耦

互聯網架構,究竟爲啥要作服務化?
原來各個業務的數據庫都混在一個大庫裏,相互join,難以拆分。
互聯網架構,究竟爲啥要作服務化?

服務化以後,底層的數據庫被隔離開了,能夠很方便的拆分出來,進行擴容。

好處六:提供有限接口,無限性能

在服務化以前,各業務線上遊想怎麼操縱數據庫都行,遇到了性能瓶頸,各業務線容易扯皮,相互推諉。

服務化以後,服務只提供有限的通用接口,理論上服務集羣可以提供無限性能,性能出現瓶頸,服務層一處集中優化。

好處七:…

服務化不能解決全部問題,若是沒有碰到這些問題,架構未必須要服務化。

一切脫離業務的架構設計,都是耍流氓。

但願你們有收穫。
互聯網架構,究竟爲啥要作服務化?
架構師之路-分享可落地的技術文章

推薦閱讀:《近期好文彙總》

相關文章
相關標籤/搜索