軟件體系架構閱讀筆記十一

1. 讀者容錯模式數據庫

讀者容錯模式(Tolerant Reader)指微服務化中服務提供者和消費者之間如何對接口的改變進行容錯。從字面上來說,消費者須要對提供者提供的功能進行兼容性設計,尤爲對服務提供者返回的內容進行兼容,或者解決在服務提供者改變接口或者數據的格式的狀況下,如何讓服務消費者正常運行。緩存

任何一個產品在設計時都沒法預見未來可能增長的全部需求,服務的開發者一般經過迭代及時地增長新功能,或者讓服務提供的API天然地演進。不過,服務提供者對外提供的接口的數據格式的改變、增長和刪除,都會致使服務的消費者不能正常工做。安全

所以,在服務消費者處理服務提供者返回的消息的過程當中,須要對服務返回的消息進行過濾,只提取本身須要的內容,對多餘或者未知的內容採起拋棄的策略,而不是硬生生地拋錯處理。架構

在實現過程當中不推薦使用嚴格的校驗策略,而是推薦使用寬鬆的校驗策略,即便服務消費者拿到的消息報文發生了改變,程序也只需盡最大努力提取須要的數據,同時忽略不可識別的數據。只有在服務消費者徹底不能識別接收到的消息,或者沒法經過識別的信息繼續處理流程時,才能拋出異常。框架

服務的消費者的容錯模式忽略了新的消息項、可選的消息項、未知的數據值及服務消費者不須要的數據項。運維

筆者當前在某個支付公司工做,公司裏幾乎每一個業務都須要使用枚舉類型,在微服務平臺下,筆者在研發流程規範中定義了一條枚舉值使用規範:分佈式

在服務接口的定義中,參數可使用枚舉值,在返回值的DTO中禁止使用枚舉值。微服務

這條規範就是讀者容錯模式在實踐中的一個實例,之因此在參數中容許使用枚舉值,是由於若是服務的提供者升級了接口,增長了枚舉值,若服務的消費者並無感知,則服務的消費者得知新的枚舉值就能夠傳遞新的枚舉值了;可是若是接口的返回DTO中使用了枚舉值,而且由於某種緣由增長了枚舉值,則服務消費者在反序列化枚舉時就會報錯,所以在返回值中咱們應該使用字符串等互相承認的類型,來作到雙方的互相兼容,並實現讀者容錯模式。設計

2. 消費者驅動契約模式blog

消費者驅動契約模式用來定義服務化中服務之間交互接口改變的最佳規則。

服務契約分爲:提供者契約、消費者契約及消費者驅動的契約,它從指望與約束的角度描述了服務提供者與服務消費者之間的聯動關係。

  • 提供者契約:是咱們最經常使用的一種服務契約,顧名思義,提供者契約是以提供者爲中心的,提供者提供了什麼功能和消息格式,各消費者都會無條件地遵照這些約定,不論消費者實際須要多少功能,消費者接受了提供者契約時,都會根據服務提供者的規則來使用服務。
  • 消費者契約:是對某個消費者的需求進行更爲精確的描述,在一次具體的服務交互場景下,表明消費者須要提供者提供功能中的哪部分數據。消費者契約能夠被用來標識現有的提供者契約,也能夠用來發現一個還沒有明確的提供者契約。
  • 消費者驅動的契約:表明服務提供者向其全部當前消費者承諾遵照的約束。一旦各消費者把本身的具體指望告知提供者,則提供者不管在什麼時間和場景下,都不該該打破契約。

在現實的服務交互設計中,上面這三種契約是同時存在的,筆者所在的支付平臺裏,交易系統在完成一筆支付後,須要到帳務系統爲商戶入帳,在這個過程當中,服務契約表現以下。

  • 生產者契約:帳務系統提供Dubbo服務化接口,參數爲商戶帳戶ID、入帳訂單號和入帳金額。
  • 消費者契約:帳務系統返回DTO,包含商戶帳戶ID、入帳訂單號、入帳金額、入帳時間、帳務流水號、入帳狀態等,而交易系統只需使用其中的入帳訂單號和入帳狀態。
  • 消費者驅動的契約:爲了保證資金安全,交易系統做爲入帳的發起者向帳務提出要求,須要帳務作冪等和濾重處理,對重複的入帳請求進行攔截;帳務系統在接受這個契約後,即便未來有任何改變,也不能打破這個限制,不然就會形成資金的損失,這在金融系統中是最嚴重的問題。

服務之間的交互須要使用的三種服務契約以下圖所示。

 

 

從上圖能夠看到,服務提供者契約是服務提供者單方面定下的規則,而一個消費者契約會成爲提供者契約的一部分,多個服務消費者能夠對服務提供者提出約束,服務提供者須要在未來遵照服務消費者提出的契約,這就是消費者驅動的契約。

3. 去數據共享模式

與SOA服務化對比,微服務是去ESB總線、去中心化及分佈式的;而SOA仍是以ESB爲核心實現遺留系統的集成,以及基於Web Service爲標準實現的通用的面向服務的架構。在微服務領域,微服務之間的交互經過定義良好的接口來實現,不容許使用共享數據來實現。

在實踐的過程當中,有些方案的設計使用緩存或者數據庫做爲兩個微服務之間的紐帶,在業務流程的處理過程當中,爲了處理簡單,前一個服務將中間結果存入數據庫或者緩存,下一個服務從緩存或者數據庫中拿出數據繼續處理。處理流程以下圖所示。

 

 

這種交互流程的缺點以下。

  • 使得微服務之間的交互除了接口契約,還存在數據存儲契約。
  • 上游的數據格式發生變化時,可能致使下游的處理邏輯出現問題。
  • 多個服務共享一個資源服務,對資源服務的運維難以劃清職責和界限。
  • 在作雙機房獨立部署時,須要考慮服務和資源的路由狀況,跨機房的服務調用不能使用獨立的資源部署模式,所以難以實現服務自治。

所以,在設計微服務架構時,必定不要共享緩存和數據庫等資源,也不要使用總線模式,服務之間的通訊和交互只能依賴定義良好的接口,一般使用RESTful樣式的API或者透明的RPC調用框架。

相關文章
相關標籤/搜索