本文轉載於本人的微信公衆號中的文章,最新文章請關注公衆號。html
目錄前端
業務背景
微服務概念
微服務技術選型
微服務架構設計
微服務架構設計落地
微服務架構設計過程當中積累的心得
總結數據庫
一、各產品系統獨立開發,代碼複用率低,系統之間互相調用,耦合嚴重,系統解耦獨立部署困難。
二、傳統的單體架構,規模愈來愈大也愈來愈笨重;當新功能的開發、功能的重構變得再也不敏捷可控;測試者的迴歸測試邊界難以琢磨;系統的上線部署也變的艱難
三、高併發訪問下沒法提供可靠性服務
四、持續集成、持續部署、持續交付等工程效率化工具嚴重缺失
五、監控系統、日誌分析等系統穩定性工具嚴重缺失
以上種種狀況,都讓咱們應對需求的變化而變得遲鈍。後端
架構確定是爲業務需求而生的,先來看看咱們面對的業務需求及其特色。平臺最主要知足兩大類業務需求:面向餐飲企業在餐飲新零售下的經營和運營需求和麪向產品及運營團隊。
具體來看:
一、餐飲新零售下的餐飲企業經營和運營的痛點緩存
如何提高營銷能力和管理會員,以更低的成本爲餐飲企業帶來更多利潤安全
如何對數據進行深度挖掘和分析,助力決策者進行運營決策服務器
如何掌握實時數據,讓決策者及時瞭解餐廳運營狀況微信
二、面向產品及運營團隊網絡
主要是提高產品控制能力,促進總體系統的良好運轉前端工程師
所以開發SAAS服務的產品迫在眉睫,須要知足快速開發、靈活升級、高性能、高可用、高穩定、簡化運維等更高的需求。
這一步的轉型,不是"快"與"慢",而是"生"與"死"。
專一於單一責任與功能獨立運行的服務,模組化方式組合出大型應用。
集中式架構:單體無分散
分佈式架構:分散壓力
微服務架構:分散能力
每一個微服務組件都是簡單靈活的,可以獨立部署。再也不像單體應用時代,應用須要一個龐大的應用服務器來支撐。
能夠由一個小團隊負責更專一專業,相應的也就更高效可靠。
微服務之間是鬆耦合的,微服務內部是高內聚的,每一個微服務很容易按需擴展。
Netflix提供了比較全面的解決方案
Spring Cloud對於Netflix的封裝比較全面
Spring Cloud基於Spring Boot,團隊有基礎
Spring Cloud提供了Control Bus可以幫助實現監控埋點
業務應用部署在阿里雲,Spring Cloud對12 Factors以及Cloud-Native的支持,有利於在雲環境下使用
首先支持Rest
團隊技術棧和實例比較單薄,但願對新的技術平滑的學習曲線和可以Hold住
小團隊,但願可以有一個比較全面的解決方案
目前團隊主要採用Spring Cloud + Spring Boot的方式實現服務化
有關技術選型詳細分析,請查看個人上一篇文章《個人技術選型》。
依賴服務變動很難跟蹤,其餘團隊的服務接口文檔過時怎麼辦?依賴的服務沒有準備好,如何驗證我開發的功能。
部分模塊重複構建,跨團隊、跨系統、跨語言會有不少的重複建設。
微服務放大了分佈式架構的系列問題,如分佈式事務怎麼處理?依賴服務不穩定怎麼辦?
運維複雜度陡增,如:部署物數量多、監控進程多致使總體運維複雜度提高。
上面這些問題咱們應該都遇到過,而且總結造成了本身的一些解決方案,好比提供文檔管理、服務治理、服務模擬的工具和框架; 實現統一認證、統一配置、統一日誌框架、分佈式彙總分析; 採用全局事務方案、採用異步模擬同步;搭建持續集成平臺、統一監控平臺等等。
微服務架構是一把雙刃劍,雖然解決了集中式架構和分佈式架構的問題,卻帶來了如上種種問題。所以咱們是須要一個微服務應用平臺才能總體性的解決這些問題。
微服務架構設計的目標,知足快速開發、靈活升級、高性能、高可用、高穩定、簡化運維等更高的需求。
微服務應用平臺的整體架構,主要是從開發集成、微服務運行容器與平臺、運行時監控治理和外部渠道接入等維度來劃分和考慮的。
開發集成:主要是搭建一個微服務平臺須要具有的一些工具和倉庫
運行時:要有微服務平臺來提供一些基礎能力和分佈式的支撐能力,咱們的微服務運行容器則會運行在這個平臺之上。
監控治理:則是致力於在運行時可以對受管的微服務進行統一的監控、配置等能力。
服務網關: 則是負責與前端的WEB應用 移動APP 等渠道集成,對前端請求進行認證鑑權,而後路由轉發。
這裏不詳細講解服務框架中每個組件,另開一篇文章來說解。
一個企業的IT建設很是重要的三大基礎環境:團隊協做環境、服務基礎環境、IT基礎設施。
團隊協做環境:主要是DevOps領域的範疇,負責從需求到計劃任務,團隊協做,再到質量管理、持續集成和發佈。
服務基礎環境:指的是微服務應用平臺,其目標主要就是要支撐微服務應用的設計開發測試,運行期的業務數據處理和應用的管理監控。
IT基礎設施:主要是各類運行環境支撐如IaaS (VM虛擬化)和CaaS (容器虛擬化)等實現方式。
服務間的通訊,每每採用HTTP+REST 和 RPC通訊協議。
HTTP+REST,對服務約束徹底靠提供者的自覺。
特色是簡單,對開發使用友好。
缺點治理起來困難,鏈接的無狀態,缺失多路複用、服務端推送等。
RPC對通訊雙方定義了數據約束。
鏈接大多基於長鏈接以得到性能的提高及附帶的服務端推、調用鏈路監控埋點等,加強了系統的附加能力。
缺點是對調用端提出了新的要求。
綜合來看,RPC從性能、契約優先來講具備優點,如何作到揚長避短呢?
引入GateWay層,讓REST與RPC的優勢進行融合,在GateWay層提供REST的接入能力。
之前的單體應用之間互相調用時配置個IP或域名就好了,但在微服務架構下,服務提供者會有不少,手工配置IP地址或域名又變成了一個耦合和繁瑣的事情。那麼服務自動註冊發現的方案就解決了這個問題。
咱們的服務註冊發現能力是依賴SpringCloud Eureka組件實現的。服務在啓動的時候,會將本身要發佈的服務註冊到服務註冊中心;運行時,若是須要調用其餘微服務的接口,那麼就要先到註冊中心獲取服務提供者的地址,拿到地址後,經過微服務容器內部的簡單負載均衡期進行路由用。
Eureka Server特色:
Eureka Client會緩存服務註冊信息
Eureka Server的註冊信息只存儲在內存中
Eureka的註冊只針對application級別,不支持更細粒度的服務註冊,如單個服務Rest
服務每隔30秒向Eureka Server發送心跳,不建議修改心跳時間。Eureka用這個時間來判斷集羣內是否存在大範圍的服務通訊異常
若是在15分鐘內有85%的服務沒有被續約,則Eureka Server中止移除已註冊的服務,以保障已註冊的服務信息不丟失
Eureka Server之間的數據同步,採用全量拉取,增量同步的方式
Eureka 知足分佈式事務中的CAP理論中的AP
微服務分佈式環境下,一個系統拆分爲不少個微服務,必定要告別運維手工修改配置配置的方式。須要採用集中配置管理的方式來提高運維的效率。配置文件主要有運行前的靜態配置和運行期的動態配置兩種。
靜態配置一般是在編譯部署包以前設置好。
動態配置則是系統運行過程當中須要調整的系統變量或者業務參數。
要想作到集中的配置管理,那麼須要注意如下幾點。
配置與介質分離,這個就須要經過制定規範的方式來控制。
配置的方式要統一,格式、讀寫方式、變動熱更新的模式儘可能統一,要採用統一的配置框架。
須要運行時須要有個配置中心來統一管理業務系統中的配置信息。
概念抽象:
介質,是源碼編譯後的產物與環境無關,多環境下應該是能夠共用的如:jar
安全認證方面,咱們基於Spring Security OAuth2 + JWT作安全令牌,實現統一的安全認證與鑑權,使得微服務之間可以按需隔離和安全互通。
認證鑑權必定是個公共的服務,而不是多個系統各自建設。
微服務架構下,相對於傳統部署方式,存在更多的分佈式調用,那麼「如何在不肯定的環境中交付肯定的服務」,這句話能夠簡單理解爲,我所依賴的服務的可靠性是沒法保證的狀況下,我如何保證本身可以正常的提供服務,不被我依賴的其餘服務拖垮?
咱們採用的方案:
合理的超時時間
合理的重試機制
合理的異步機制
合理的限流機制(調用次數和頻率)
合理的降級機制
合理的熔斷機制
推薦SEDA架構來解決這個問題。
SEDA : staged event-driven architecture本質上就是採用分佈式事件驅動的模式,用異步模擬來同步,無阻塞等待,再加上資源分配隔離結起來的一個解決方案。
分佈式事務-CAP
C 分佈式環境下多個節點的數據是否強一致
A 分佈式服務能一直保證可用狀態
P 網絡分區的容錯性
分佈式事務-策略
避免跨庫事務,儘量相關表在同一個DB
2PC 3PC TCC 補償模式等, 耗時且複雜
基於MQ的最終一致性 簡單、高效、易於理解
將遠程分佈式事務拆解成一系列本地的事務
分佈式事務-基於MQ
服務拆分方式
AKF擴展立方體,是抽象總結的應用擴展的三個維度。
X軸 擴展部署實例,就是講單體系統多運行幾個實例,作個集羣加負載均衡的模式。
Y軸 業務領域分離,就是基於不一樣的業務拆分。
Z軸 數據隔離分區,好比共享單車在用戶量激增時,集羣模式撐不住了,那就按照用戶請求的地區進行數據分區,北京、上海、深圳等多建幾個集羣。
服務拆分要點
低耦合、高內聚:一個服務完成一個獨立的功能
按照團隊結構:小規模團隊維護,快速迭代
單庫單表難以支撐日益增加的業務量和數據量,服務拆分了數據庫也跟着拆分。
5.9.1 模式
垂直拆分
水平拆分
5.9.2 原則
儘量不拆分
避免跨庫事務
單表量級1000w
避免垮褲join(冗餘、全局表)
日誌主要有三種,系統日誌,業務日誌,跟蹤日誌。有了這些日誌,在出問題的時候可以幫助咱們獲取一些關鍵信息進行問題定位。
要想作到,出了問題可以追根溯源,那麼咱們須要一個能夠將整個完整的請求調用鏈串聯起來的標識,這個標識可以讓咱們快速定位問題發生的具體時間地點以及相關信息,可以快速還原業務交易全鏈路。對這些日誌與流水的細節處理,對於系統運維問題定位有很是大的幫助。一般開源框架只是提供基礎的框架,而設計一個平臺則必定要考慮直接提供統一規範的基礎能力。
分佈式跟蹤
對於前面提到的微服務帶來的依賴管理問題,咱們須要提供API管理能力。說到API管理,那首先就用提到服務契約。
服務契約,主要描述服務接口的輸入輸出規格標準和其餘一些服務調用集成相關的規格內容。
有了服務契約,研發人員就能夠方便的獲取到依賴服務變動的狀況,可以及時的根據依賴服務的變化調整本身的程序,而且可以方便的進行模擬測試驗證。
根據契約生成模擬服務也就是咱們常說的服務擋板,這樣即便依賴的其餘服務還沒法提供功能,咱們也能夠經過擋板來進行聯調測試。
咱們要作穩定、高效、易擴展的微服務應用,實際上咱們須要作的事情仍是很是多的。若是沒有一個統一的微服務容器,這些能力在每一個微服務組件中都須要建設一遍,也很難集成到一塊兒。有了統一的微服務運行容器和一些公共的基礎服務,前面所提到的微服務架構下部分組件重複建設的問題也迎刃而解。
在運維方面,首先咱們要解決的就是持續集成和持續交付,可以方便的用持續集成環境把程序編譯成介質包和部署包並持續穩定的部署到每一個環境。
概念抽象:
介質:是源碼編譯後的產物與環境無關,多環境下應該是能夠共用的。如:jar
配置:則是環境相關的信息。
部署包=配置+介質。
就微服務應用平臺自己來講,並不依賴DevOps和容器雲,開發好的部署包能夠運行在物理機、虛擬機或者是容器中。然而當微服務應用平臺結合了DevOps和容器雲以後,咱們就會發現,持續集成和交付變成了一個很是簡單便捷而且又可靠的過程。簡單幾步操做,整套開發、測試、預發或者生產環境就可以搭建完成。
整個過程的複雜度都由平臺給屏蔽掉了,經過三大基礎環境的整合,咱們可以使分散的微服務組件更簡單方便的進行統一管理和運維交付。
技術團隊組織 – 小團隊
根據「康威定律」,軟件架構是由組織的架構決定的,所以按照貝索斯「two-pizza」團隊的理論和敏捷方法,構建小的團隊,能夠有效減小溝通成本,有利於團隊的自治。
咱們經過讓一個小的團隊有比較全面的建制,Leader(熟悉業務和技術)+ 前端工程師 + 後端工程師,每每能夠可以比較獨立地承接一個或者幾個業務的工做。這樣團隊成員總體負責一個或者幾個業務模塊,能夠極大地提升團隊成員的參與感、使命感和責任感,團隊成員相互幫助,高度自治,你們要麼一塊兒成功,要麼一塊兒失敗。
技術團隊組織 – 團隊劃分
團隊的劃分,是按照業務線劃分的。隨着業務的複雜度的增長,能夠按照業務/子業務線的方式來劃分團隊,但並非絕對的扁平化,而是嚴格遵循two-pizza原則。
業務線的劃分經常按業務細分,技術團隊要負責支持所有業務線,所以技術團隊的劃分一般按系統或者是業務,Two pizza團隊的原則在組織層級的任何部分都適用,當人數過多時,必須繼續拆分。
技術團隊組織 – 團隊合做
技術團隊組織 – 結果導向
主人翁意識(Ownership)
行動力(Bias for Action)
吃本身的狗糧(Eat your dog food)
• 工程師負責從需求調研、設計、開發、測試、部署、維護、監控、功能升級等一系列的工做,也就是說軟件工程師負責應用或者服務的全生命週期的全部工做
• 運維是團隊成員的第一要務,在強大的自動化運維工具的支撐下,軟件工程師必須負責服務或者應用的SLA
開發人員參與架構設計,而不是架構師參與開發
• 研發人員是Owner,對業務和團隊負責
• 強調抽象和簡化,將複雜的問題分解成簡單的問題,並有效解決,避免過分設計
• 鼓勵用新技術解決問題,但強調掌控力
深刻理解業務
設計階段要追求完美,實踐階段要考慮實際狀況做出平衡
容錯能力
監控先行
任何上線可回滾
微服務架構是技術升級,但更多的是管理模式的升級、思惟方式的轉變。
-EOF-