天天看點

從單體應用轉為分布式系統:來自Deliveroo的實踐

過去一年中,deliveroo在商業和it領域成長迅速,這導緻它的大型單體應用面對不少的技術挑戰。greg beech在近期的qcon倫敦大會演講中指出,deliveroo對此問題的解決方案并非依靠微服務,而是向分布式轉變。beech介紹了deliveroo在從單體應用轉變為分布式系統過程中的一些做法。

deliveroo公司創立于2013年,beech現任公司的首席工程師。公司起步于采用傳統ruby on rails開發的單體應用,資料存儲使用了postgresql和redis,通過不斷增大資料庫規模而處理日益增長的業務。一年前,他們需要運作大約20台heroku托管伺服器。目前運作的伺服器規模達數百台,這已成為keroku上部署的最大規模應用,峰值情況下需要使用1800個核心和3tb的記憶體。公司由2015年的10名工程師已成長為2017年的近100名工程師,主代碼庫中的有效代碼行達到約60萬行。

采用單體程式架構是一個經過深思熟慮的決策,他們是以可以快速添加适合市場需求的特性,但是現在這種架構需要面對一些問題。由于目前單體程式的規模增長得很大,deliveroo受困于性能下降和建構時間增加的問題,建構時間已經從兩年前的7分鐘左右增加到目前的兩個小時左右,進而延緩了開發的速度。大型單體程式也會導緻可靠性下降,因為出現一個問題就可能使得所有的服務當機。

deliveroo的解決方案是轉向分布式,實作中采用了一種将單體程式切分為三大類“十二要素”(twelve-factor)應用的方法。這三類應用分别是領域服務(domain service)、外圍服務(edge service)和用戶端應用(client apps for the ui),事件總線為這些服務提供了支援。

領域服務是:

占有領域的重要部分。這些服務占有了領域的重要部分,這些部分隻有緊密粘合在一起才具有作用。這就是beech不喜歡稱其為微服務的原因所在。 暴露内部真實的rest api,包括超媒體。 從事件總線收發事件。 可以使用其它域服務的api。

外圍服務是:

不具有任何一部分領域。 向外部暴露聚合的api。 從事件總線接收事件。 可以使用其它外圍服務和領域服務的api。

在這種分布式解決方案中,不存在共享的資料存儲。每個應用都具有自身的資料存儲,除非存在例外情況,否則每個應用的資料存儲是不能被其它的應用通路的。此外,所有資料是作為rest api方式暴露的,beech指出這是真正包含超媒體的rest。舉個例子,api傳回的集合(collection resource)是一系列到實體的連結,而非内嵌的對象。他同時指出,rpc是不允許使用的。

在建立、更新或删除實體後,領域服務會通過事件總線發送事件,他們将這種技術稱為“呈現狀态通知”(rsn,representational state notification)。事件中從不包含載體,隻是連結到事件相關實體。這樣做的部分原因是出于避免總線成為資料損失的一個關鍵源頭。但是一些非關鍵的不可變值對象是可以在消息中發送的,這是一種例外情況。

beech指出雖然deliveroo對于服務如何建構、如何分層及如何通信給出了相當強有力的指南,但依然可以從簡單處着手,按自己需要去演化成一個更為複雜的架構。這樣做的目的在于,允許團隊就像具有自身問題切入點和目标的初創公司那樣運作,按團隊需求演化自身的架構,并在分布式架構經驗有限的條件下取得成功。

本文轉自d1net(轉載)