摘要
本次演講是由鏈家網基礎架構部高階研發工程師劉思賢帶來基於Spring Cloud的微服務實踐經驗分享。
閱讀字數:2632 | 5分鐘閱讀
嘉賓演講視訊回顧及PPT連結:t.cn/REnMM2q
回到2015年
在2015年,我受朋友的邀請加入了愛油科技,擔任愛油科技的架構師。愛油科技做了十年傳統行業的成品油交易,開始進行網際網路化的轉型。它有非常重的線下業務,這些線下業務會通過資訊化網際網路的手段搬到線上進行一系列的改造。
我接手公司業務的時候只有一個單體應用,通過團隊大約兩年的維護,建設了很多不同的業務系統等。在我瞭解到這家公司的情況之後,和CTO討論決定通過微服務的方式來改造整個系統。
業務的變遷
為什麼要做微服務呢?首先就要聚焦到我們當前業務的變化。
以前的業務通常是一個網站打天下,而現在各種各樣的新媒體渠道成為了我們業務的重要入口,傳統單一網站的形式已經不能滿足我們的要求了。
對愛油科技而言,以前的業務通常是線上收單線下處理,現在這家公司的重要使命就是要把所有的業務流程搬到線上,讓它流轉得更有效率。
在以往的系統中,使用它的主要使用者是系統管理員,他們通過後臺來維護一些商品的資訊等等。而在我們想要把所有業務流程搬到線上之後,它面臨的變化就是業務人員需要用後臺,使用後臺的方式也從單一的網站轉變到了APP隨時辦公的場景。
研發犯難
需求變化侵蝕架構,像熔化的反應堆芯;
被技術平臺綁架,大炮打蚊子;
協作困難,牽一髮而動全身。
架構分層和基本原則
期望目標
不繫結到特定的語言和框架,可以將多種多樣的語言快速實現業務最有效率地去交付業務價值為目標;
當一套微服務體系中引入多種語言的時候,必然涉及到多種語言、多種框架之間的整合。鬆散耦合的體系結構便於多種語言框架的整合;
簡單、容易落地、方便擴充套件。
原則
業務服務層服務完全對等;
業務服務層服務必須是無狀態的,這能保證業務服務層的所有服務能提供對外擴充套件的能力;
接入層服務之間禁止相互呼叫;
接入層服務不能包含業務邏輯,這一層是輕和薄,面向渲染、面向輸出,不面向業務邏輯的處理;
業務介面必須是RESTful風格,因為我們期望在我們的整體架構中不僅僅涵蓋Java的東西,也可以涵蓋其它語言的一系列服務;
所有服務必須執行在容器裡。我們整體團隊有限,不可能提供大量的人力物力去進行運維等操作,利用容器可以幫助我們進行服務的治理,以節約大量的資源。
SPRING CLOUD快速搭建微服務框架
服務註冊和發現
在Docker整個容器技術中,我們發現Consul作為一個服務註冊和發現中心,正好可以納入到我們的體系當中,直接進行使用。
Consul的服務註冊其實要比後來Spring Cloud Consul提供的Config的服務更加容易落地、更有實用性。
仍待解決
在這套方案中當時有些問題還沒有得到很好的解決。
Consul服務註冊發現與七層Nginx聯動。我們期望的是當一個服務啟動之後,它能夠直接被Nginx的七層發現,我們不用再手工地去更改Nginx的配置。
另一個就是灰度釋出的問題。因為在整個現有的Spring Cloud的裡,去做一個服務釋出20%的流量到一個新的版本這件事情,現在處理起來還比較困難,很難把這20%的服務標記出來。
Consul作為配置中心
統一管理Spring Cloud專案的配置檔案;
為接入層服務下發配置。
仍待解決
Consul作為配置中心依然有些問題沒有解決。
配置的版本化管理。一個配置修改前後的版本差異是要能夠訪問得到的,不然線上修改配置一旦出現問題,就無法很快地還原配置。
灰度釋出。在目前Spring Cloud的基礎設施中還很難允許在一個叢集中20%用這個配置,80%用另一個配置。我們需要做一些定製化開發來解決這個問題。
服務整合
服務層Node:Consul、Brake
接入層Node:request to zuul
PHP接入層:guzzle to zuul
領域驅動設計指導業務服務開發
業務到微服務
我們把這種天然的業務彼此獨立或隔離叫做界限上下文。在界限上下文裡面,它們使用相應的統一語言描述業務。在每個領域內它們有自己的模型,圍繞這個模型進行建模,它們各種有統一的語言。這樣就天然地把它們拆成了成員微服務和交易微服務。
從業務到微服務的過程中,其實包含了兩種訊息的傳遞。一個最基本的觀點就是,物件和物件之間訊息的傳遞是通過方法呼叫來進行的。我們有同樣的方法,就是一個服務去呼叫另外的服務,它產生的結果會作為這個服務的使用。
基於剛才領域驅動設計的觀點,領域模型被放在了六邊形架構的中間,所有和領域進行互動的東西都是通過六邊形架構的邊來進行。
還有一類是非同步的訊息。比如一個客戶下單之後要給他建立相應的物流訂單,就是一個領域內產生的訊息通過領域事件的方式向另一個領域進行傳播。
領域事件的傳遞
領域事件的傳遞很出現一個問題,每個不同的微服務使用不同的MQ服務,它們之間的訊息怎樣進行互動?
我們選用了一個訊息服務的中介軟體,每一個需要傳送事件的微服務都會維護一個Event Topic,然後再維護一個從其它領域內傳來訊息的Page。當一個事務提交之後,每個事件會被投到Topic裡面,Topic收到訊息服務中,訊息服務再按照訂閱關係投遞到相應的Event Queue裡面。它們各自消費這個Event Queue就能處理這個事件。
訊息服務
整個訊息服務我們使用了某雲端計算廠商提供現成的訊息服務作為我們的訊息中介軟體。
分包/模組原則:高內聚、低耦合;
通過領域模型表達領域知識提高內聚性;
應用層使用領域模型;
防腐層提供領域層所需的實現,防止實現耦合到領域。
這時大家所說的實體變成了失血的領域模型。而對於物件導向、語言來講,它表現業務規則、表現知識最大的表現力就是物件之間的互動。
這種更具領域知識表現力的設計方式會比事務指令碼的方式更容易維護。
原則
以界限上下文劃分微服務;
領域模型表達領域知識,高內聚;
服務與服務之間通過Rest和MQ整合,低耦合。
基礎設施與DEVOPS
基礎設施
物件儲存:S3/OpenSwift,儲存與計算分離;
訊息服務:動態定義訊息訂閱及路由;
容器資源管理:Rancher、SwarmKit;
日誌服務:Docker、Rsyslog、Logstash。
DevOps
DevOps每個分支都會提供相應的構建,構建出的結果就是標準化的映象,標準化映象帶來了Dev、QA、Production環境統一。
價值
整體實施完微服務之後,給公司帶來的價值是新業務最短1週上線,10人團隊可以維護20餘種微服務,每日數次線上釋出,每週里程碑釋出,全年核心業務可用性高達99.95%。
在整個微服務架構落地中,技術體系的建設至關重要。
我今天的分享就到這裡,謝謝大家!