微服務的目標是提升響應能力,下降複雜度,讓一切去中心化是微服務的最高宗旨。
隨着研發團隊的項目工程的增長、代碼量的膨脹、團隊人員的增加,傳統的單體架構的弊端愈來愈凸顯,嚴重影響了業務的快速創新和敏捷交付。隨行付在2015年末爲了解決傳統單體架構面臨的挑戰,前後經歷了單體架構、系統模塊拆分以及到如今的微服務化。算法
微服務架構並不是銀彈,它的實施過程當中會面臨不少的陷阱和挑戰、幾乎影響到整個軟件開發的生命週期,稍有不慎,會致使整個微服務改造的效果大打折扣,甚至失敗。緩存
本公衆號接下來的一段時間會協同隨行付架構部、隨行付技術委員會等技術團隊,結合隨行付的一些實際經驗,論證微服務架構實施的道與術。安全
爲何要作微服務化?能夠從如下三個方面看爲何搞微服務。架構
能夠用變化的成原本衡量架構的好壞。而架構的目的是管理複雜性、易變性和不肯定性,以確保系統在進化過程當中,架構的變化不會對應用產生沒必要要的負面影響。保證業務和研發效率的敏捷、保證易變應用頻繁響應市場需求而中臺部分的影響儘量的小。負載均衡
10幾年前,一提到架構,大多數人都會認爲,架構=性能+高可用。隨着如今的技術不斷更新(Docker、人工智能、區塊鏈等技術)、各種開源軟件異軍突起、DevOps理念深得人心、敏捷開發成爲主流開發模式等等,性能和高可用已經再也不是那麼棘手的問題。應用如何可持續發展?產品如何能快速上線/快速迭代?可維護性、可擴展性、成本,開始慢慢成爲不少架構師的關注點。而微服務架構的根本目的就是下降複雜性。框架
採納微服務架構首當其衝的問題就是根本沒有一個肯定的、良好定義的算法能夠完成服務的拆分工做。像軟件開發自己,服務的拆分和定義更像是一門藝術。更糟糕的是,若是你對系統的服務拆分出現了誤差,你頗有可能會構建出一個「分佈式的單體應用」,一個包含了緊耦合服務的必須部署在一塊兒的系統。這將會把單體架構和微服務架構二者的弊端集於一身。運維
微服務一個明顯的表象就是隨着服務的增多,若是繼續沿用傳統的測試模式就會遇到瓶頸,爲了保證高效的迭代,儘可能作到測試自動化。經過自動化讓測試也能夠「一處編寫,到處運行」、讓迴歸測試平常化。分佈式
當互聯網發展到今天,業務要保持對市場變化的一個高效響應,自動化運維就是提高交付速度的一個重要環節。微服務拆分以後,每一個服務均可以獨立部署,再也不是固定的時間段去升級,人肉運維已經成了阻礙進步的絆腳石了。微服務
硬件環境、服務狀態、系統健康度、服務調用狀況、異常的實時告警以及生產事故的事先預警等等。監控在實施微服務過程當中相當重要。性能
必定要使用成熟技術,充分考慮新技術帶來的性價比。所謂成熟不只僅是指有良好的社區活躍度、穩定性、節約開發成本、提升開發效率。更多的是指在隨行付的技術普適度,說白了就是有多少人會,出了問題有多少人能hold住。
權衡好哪些服務是最終一致、哪些必須是強一致。而強一致的保障機制是什麼?框架層和應用層相互互補來共同保障數據一致性。
對於無狀態服務,首先說一下什麼是狀態。若是一個數據須要被多個服務共享,才能完成一筆交易,那麼這個數據被稱爲狀態。進而依賴這個「狀態」數據的服務被稱爲有狀態服務,反之稱爲無狀態服務。那麼這個無狀態服務原則並非說在微服務架構裏就不容許存在狀態,表達的真實意思是要把有狀態的業務服務改變爲無狀態的計算類服務,那麼狀態數據也就相應的遷移到對應的「有狀態數據服務」中。
場景說明:例如咱們之前在本地內存中創建的數據緩存、Session緩存,到如今的微服務架構中就應該把這些數據遷移到分佈式緩存中存儲,讓業務服務變成一個無狀態的節點。遷移後,就能夠作到按需動態伸縮,微服務應用在運行時動態增刪節點,就再也不須要考慮緩存數據如何同步的問題。
無狀態通訊,咱們推薦使用Restful通訊風格,由於他有不少好處:
AKF擴展立方體,《架構即將來》一書中提出的可擴展模型。理論上按照這三個擴展模式,能夠將一個單體系統,進行無限擴展。
X 軸 :是水平復制。好比講單體系統多運行幾個實例,作個集羣加負載均衡的模式。
Z 軸 :是數據分區,好比按照用戶請求的地區進行數據分區,北京、上海、四川等多建幾個集羣。
Y 軸 :是微服務的拆分模式,就是基於不一樣的業務進行拆分。
舉例:好比打車APP,一個集羣撐不住時,分了多個集羣,後來用戶激增仍是不夠用。分析後發現打車APP上主要用戶是乘客和車主,就將打車應用拆成了三個乘客服務、車主服務、支付服務。三個服務的業務特色各不相同,獨立維護,各自均可以再次按需擴展。
根據業務能力拆分。瞭解過面向對象的人應該都據說過「單一職責原則」,即每個類都擁有一個職責。好比一個搬磚類,它既能夠蓋房子,也能夠用來拍人,這時搬磚就擁有了兩個職責,因此咱們應該把類拆分爲兩個。微服務也是一個道理,咱們應該作到一個服務是用來作一件事情的。
緊密關聯的事物應該放在一塊兒,每一個服務是針對一個單一職責的業務能力的封裝,專一作好一件事情。(每次只有一個更改它的理由)。
領域驅動設計。咱們怎麼按領域來劃分服務呢?對,咱們能夠按業務進行拆分,好比財務、訂單、倉庫等等。這樣咱們的團隊也能夠拆分開來分別負責不一樣的服務,這樣不只項目清晰了,就連公司內部的組織結構權責分配也變得清晰了。
剛纔從橫向來看咱們能夠按業務領域拆分,縱向的呢?咱們能夠按層次進行拆分,好比最底層的數據層、基礎設施層以及與業務無關的推送、郵件、短信等等。咱們還能夠按安全性、性能等須要特別關照的以及通用的功能進行抽離沉澱。
掌握了領域驅動設計不只遵照了高內聚、鬆耦合還符合了單一職責原則,那還不趕忙拆起來?
避免過早拆分。過早的劃分服務,可能發展一段時間以後,服務的邊界會和以前有所不一樣,致使不少跨服務的修改,代價愈來愈高,最終又變成了單塊系統。因此一開始咱們應該按照較粗的粒度進行劃分,而是否拆分爲更小的服務,應該由團隊組織結構決定,若是團隊對拆分後服務的維護成本更大了,那就應該放棄拆分更小的粒度。
微服務的開發會面臨依賴滯後的問題。在單體架構時,你們須要什麼,每每喜歡本身寫什麼,這實際上是沒有太嚴重的依賴問題。可是到了微服務時代,微服務是一個團隊或者一個小組提供的,這個時候必定沒有辦法在某一個時刻同時把全部的服務都提供出來,「需求實現滯後」是必然存在的。
例如:A要作一個商戶黑名單校驗,依賴服務提供者B。而B有其餘更重要的任務,致使該服務的開發優先級排的比較低,沒法知足A的交付時間點。A會面臨要麼等待,要麼本身實現一個服務。
一個好的實踐策略就是接口先行,基於契約,語言中立。服務提供者和消費者解耦,並行開發,提高產能。不管有多少個服務,首先須要把接口識別和定義出來,而後雙方基於接口進行契約驅動開發,利用Mock服務提供者和消費者,互相解耦,並行開發,實現依賴解耦。
採用契約驅動開發,若是需求不穩定或者常常變化,就會面臨一個接口契約頻繁變動的問題。對於服務提供者,不能由於擔憂接口變動而遲遲不對外提供接口,對於消費者要擁抱變動,而不是抱怨和抵觸。要解決這個問題,一種比較好的實踐就是管理 + 技術左右開弓:
代碼經過Sonar掃描(隨行付Sonar中定製208條規則)
有80%以上的單元測試複雜度
容許接口變動,可是對變動的頻度要作嚴格管控
提供全在線的API文檔服務(例如Swagger UI),將離線的API文檔轉成全在線、互動式的API文檔服務
API變動的主動通知機制,要讓全部消費該API的消費者可以及時感知到API的變動
契約驅動測試,用於對兼容性作迴歸測試
隨行付微服務平臺是以DevOps爲理念,基於Spring Boot、Spring Cloud、React、React Native、容器技術、人工智能等,面向微服務應用的PaaS平臺。實現基礎設施雲化、應用架構現代化和開發流程敏捷化。
如圖上所示,咱們圍繞Spring Boot、Spring Cloud作了不少功能的擴展,讓Spring生態在隨行付能生長出更多的解決實際問題的「果實」,一樣並無盲目的造輪子。因文章篇幅,技術篇更多內容會在系列文章中着重介紹,會從各個中間件入手介紹隨行付金融科技技術生態。