分散式服務架構:原理 設計與實踐(讀書總結)
文章目錄
- 1. 分散式微服務架構設計原理
- 1.1 從傳統的單體架構到到服務化架構
- 1.2 從服務化到微服務
- 1.3 微服務架構的核心要點和實現原理
- 1.4 Java平臺微服務架構的專案組織形式
- 1.5 服務化管理和治理框架的技術選型
- **總結**
- 2.徹底解決分散式系統一致性的問題
- 3. 服務化系統容量評估與效能保障
- 3.1 架構設計和非功能質量
- 3.2 全面的非功能質量需求
- 3.3 典型的技術評審提綱
- 3.4 效能和容量評估經典案例
- 3.5 效能評估參考標準
- 3.6 效能測試的方案設計與最佳實踐
- 3.7 有用的壓測工具
- 總結
- 4. 大資料日誌系統的構建
- 5. 基於呼叫鏈的服務治理系統設計與實現
- 6.java服務的線上應急和技術攻關
1. 分散式微服務架構設計原理
1.1 從傳統的單體架構到到服務化架構
架構的演進答題分為三個階段:
- JEE架構階段
- SSH架構階段
- 服務化架構階段
- JEE架構階段主要劃分為 UI互動研發團隊(前端研發工程師)、後臺研發工程師和DBA研發團隊。SSH架構 階段劃分上與JEE架構階段停留在相同層次上,不同點在於使用springMVC的劃分性質,使用了Struts、Spring、Hiberate幾個框架使得開發變得簡單。
- 服務化架構不同於以上兩種單體層次的架構模式,它解決了單體程式的高耦合和高併發程式無法突破瓶頸的限制。而SOA則是服務化的典型代表,它通過將服務進行詳細的設計規劃,拆分成一個個小型的服務,這些服務都必須在其定義的介面和契約上完成,並且通過諸如HTTP、TCP或IP等網路通訊協議進行網路通訊。典型的兩種SOA實現方式是:Web service(註冊發現模式) 和 ESB(匯流排模式),現在大型網際網路公司主流喜歡使用 Zookerper 和 Dubbo 的服務化架構模式。
1.2 從服務化到微服務
SOA服務化是為了讓每個服務職責單一、更簡單和易於擴充套件,但存在歷史遺留問題。而微服務架構則致力於鬆耦合和高內聚的效果,其強調每個服務的獨立開發、維護、部署。
- 與傳統的結構相比,微服務更加的靈活,可以平滑的進行水平擴充套件。具有子服務獨立打包部署的特點,讓更專業的人做專業的事。
- 與SOA服務相比較,目的不同、部署方式不同以及服務粒度不同。
- 目的性 SOA強調有效整合、歷史應用整合、應用流程編排。微服務強調有效的拆分應用,實現敏捷開發和部署。
- 部署方式 SOA通過將元件化模組打成一個WAR包部署在一臺應用伺服器上。微服務採用敏捷擴容和縮容的docker技術來進行自動化部署。
- 服務粒度 SOA強調契約化,內部實現通常是粗粒度的。微服務將就單一職責原則,一般會將整體應用按照業務流程拆分為更細的粒度。
1.3 微服務架構的核心要點和實現原理
微服務的實現原理核心劃分一下六個方面:
- 微服務架構中的團隊職能劃分
- 去中心化的服務治理
- 微服務互動模式:讀者容錯模式、消費者驅動契約模式和去共享資料模式
- 微服務分解和組合模式:服務代理模式、服務聚合模式、服務串聯模式、服務分支模式、服務非同步訊息模式和服務共享資料模式
- 微服務容錯模式:艙壁模式(容器和執行緒池分組)、熔斷模式、限流模式(計數器 令牌桶 訊號量等)和失效轉移模式
- 微服務劃分粒度
- 微服務職能劃分講求專業人做專業事,理論上一個服務需要一個團隊去進行開發維護,而現實中不可能按照康威定律去執行的。
- 去中心化 就是儘可能不要去設定中心化管理中心,我們常用的Dubbo和Zookerper則是中心化管理模式,我們如果使用這種模式也要做到服務宕機的降級化處理,比如點對點的hessian遠端呼叫。
- 微服務的互動通常來講,容錯就是我們消費方在消費服務是儘可能獲取需要的資料,不要丟擲異常,除非完全不能使用;消費者驅動模式就是消費方可以對提供者方提出具體的要求,提供者在對介面進行修改時要遵循此種約束;去資料共享通俗的講就是不要公用相同資料庫和快取,每個服務需要有自己獨立的伺服器和快取。
- 微服務組合模式 中我們最常用也是最應該使用的是服務聚合模式,它將基礎服務可以組合成我們需要的服務,並且相比於分支模式,我們的服務呼叫結構可以更加的清晰明瞭。
- 微服務的治理我們需要有明確的模式,四種我們常用的模式都是我們需要進行分析和實踐進行總結的。限流模式也是在高併發應用中經常使用到的模式。而失效轉移模式中使用比較多的是補償機制。
- 微服務的劃分則需要我們根據業務和公司團隊配置來進行合理的劃分就可以了。
1.4 Java平臺微服務架構的專案組織形式
- 通常來講,我們實際應用中,使用MVC的模式,表現層,服務層和實現層。那麼 微服務專案的層級結構 也是類似,表現層打war包,包含服務層和實現層的jar包。
- 微服務工程需要實現自動化的自動部署和持續整合功能,包含:程式碼管理、自動編譯、釋出QA、自動化測試、效能測試、準生產環境部署和測試、生產環境部署等。
1.5 服務化管理和治理框架的技術選型
- 服務化管理和治理的 RPC框架使用比較多的是Hessian和Burlap,使用HTTP銅須協議,資料傳輸使用XML格式,可以跨語言。而相對的RMI框架和 Spring HTTPInvoker框架都不支援語言的跨越,因此使用率比較少。
- 服務化框架 我們最常用的Dubbo框架,提供了高效能的RPC遠端服務呼叫,還提供了基本的服務監控、治理和排程的功能,最近已經開源給Apache。還有諸如淘寶的HSF、Facebook 的Thrift、Apache Web Service下的子專案 AXIS等。
- spring-cloud 目前非常強大的微服務框架系列。基於spring—boot,集成了NetFilx,包含了各大服務元件,如:Eureka、Hystrix、Ribbon、Zuul等。
總結
從傳統的單體服務演進到SOA服務化架構,再到高層次的微服務架構,技術上面我們得到了提升和轉變。我們總結微服務有如下特點:
- 將傳統單體服務拆分成模組化元件的網路服務。
- 按照業務拆分服務,劃分服務團隊,提升團隊作戰效率,減少團隊溝通成本。並且每一個團隊可以獨立進行開發運營和部署。
- 微服務講求合理拆分、分層和構建,需要平臺可以持續的進行釋出,並進行敏捷開發和部署。
- 微服務常用的設計模式,包含了互動模式、組合模式、容錯模式等。
- 微服務的架構選型,現使用spring-cloud系列。
2.徹底解決分散式系統一致性的問題
2.1 什麼是一致性
傳統的IT行業一致性是強一致性,而在網際網路時代,由於請求併發量大,資料量也大的特點,這裡的一致性是弱一致性,所謂的如弱一致性就是分散式應用系統之間的一致性和資料的一致性。
2.2 一致性問題
- 下訂單和扣庫存
保持兩者的同時成功或同時失敗。
- 同步呼叫超時
系統A呼叫系統B超時,得到超時反饋但不知道系統B是否完成了特定功能,無法給予使用方結果。 - 非同步回撥超時
系統A非同步呼叫系統B,但發生故障導致系統A一直沒能收到返回結果,使得兩個系統之間的狀態不一致。 - 掉單
兩個系統處理業務的上下游,但存在一個系統存在處理任務的請求,另外一個系統不存在,出現掉單。 - 系統間狀態不一致
與掉單類似,但不同點在於,請求存在與兩個系統,但請求的狀態不一致。 - 快取與資料庫不一致
討論快取與資料庫是保持強一致性還是弱一致性。 - 本地快取節點間不一致
本地快取的資料如果存在頻繁的變更或修改,則在某一時刻各節點間的資料不一致,請求過來後進入了不同的系統,可能出現請求被處理兩次的情況。 - 快取資料結構不一致
存入到快取中的資料可能沒有完全獲取,導致快取中資料介面缺失,在呼叫介面時可能出現數據介面不一致丟擲異常,如NullPointerException等。
2.3 解決一致性問題的模式和思路
- 酸鹼平衡理論
主要有三大理論:關係型資料庫遵循的ACID理論、分散式事務的CAP理論和CAP解決方案的BASE理論。我們基於BASE理論的軟狀態原理,可以保持系統狀態在一定時間內不需要一直,只需要保證系統狀態的最終一致性。這裡我們可以解決一致性的第一個問題。- 分散式事務一致性協議
主要有大三協議: 兩階段協議(準備階段和提交階段,可能出現阻塞、腦裂、單點故障)、三階段協議(增加了一個問詢階段,降低了阻塞和不一致的風險)、阿里巴巴的TCC協議(簡化的兩階段協議,分為try、confirm、Cancle三個步驟)。- 保證最終一致性的模式
查詢模式、補償模式、非同步確保模式 三種模式可以解決一致性問題的2.3問題。
定期校對模式 是通過系統間的全域性唯一ID來定期校對主流程系統的操作,進行補償,可以解決問題4,5。
訊息可靠模式 希望我們通過訊息佇列來進行資料的補償等操作,要保證訊息的可靠性和冪等性。
快取一致性模式 提出快取與資料庫保持弱一致性,對於缺失資料進行回源而不放入資料庫當中。
2.4 超時處理模式
系統的互動目前有三種方式:同步呼叫、非同步呼叫、訊息佇列。
- 同步通訊中出現超時一般採用冪等的特性採用查詢模式進行重試或者快速失敗(一般有兩狀態和三狀態的區別);
- 非同步呼叫超時 通常有三種超時模式:非同步呼叫介面超時和非同步呼叫內部超時與同步三狀態一直,採用查詢補償的模式。非同步呼叫回撥超時我們一般採用定時重試的機制。
- 訊息佇列超時 主要分為生產者超時和消費者超時,我們對資料精確度不高的訊息採用拿走即消費的模式。而對於需要較高精確度的訊息我們採用手動的方式,進行資料庫儲存和訊息消費狀態的資訊返回。
- 超時補償原則 分為呼叫者超時和被呼叫者超時,呼叫者超時則是呼叫者不停的輪詢被呼叫者知道請求成功,後者則是被呼叫者努力完成任務,知道返回給呼叫者結果。一般我們處理微信業務的支付回撥則是類似的機制。
2.5 遷移開關的設計
常用的遷移設計主要有三種方式:
1.應用層面,直接進行curl呼叫;
2.配置層面,在系統配置中心直接配置;
3.標記層面,即在伺服器接收到請求後將關聯實體進行標記,確保資料的一致性。(推薦使用)
總結
介紹了什麼是一致性,分為強一致性和弱一致性,又提出了一致性八個問題:下單和減庫存、同步呼叫超時、非同步呼叫超時、掉單、系統狀態不一致、快取與資料庫不一致、本地快取節點不一致和快取結構不一致的問題。後續提出瞭解決方案,分為六大模式:查詢模式、補償模式、非同步確保模式、定期校驗模式、訊息可靠模式、快取一致性模式。又講解了具體的超時處理模式,從系統間的互動方式做了具體的分析。
3. 服務化系統容量評估與效能保障
3.1 架構設計和非功能質量
我們一般架構設計有分為三個階段:需求分析與整理 概要設計 詳細設計
非功能質量一般包含:高效能、高可用、可伸縮性、可擴充套件性、安全性、穩定性、健壯性、可測試性、可監控性等。
我們一般對系統架構進行評價使用 網際網路架構權衡分析方法(ATAM)。
3.2 全面的非功能質量需求
概要的來講可以分為 核心需求和非核心需求:
核心需求:高可用、高效能、可伸縮、可擴充套件、安全性。
非核心需求:可監控性、可測試性、魯棒性、可重用性、易用性、可維護性。
具體指標一般分為:
系統伺服器、快取、資料庫、訊息佇列。其對應的相關指標可以從部署結構指標、容量和效能指標、其他指標三個方面來進行綜合評測。
3.3 典型的技術評審提綱
我們從方案設計時做出的一系列方案和方案對比評估,主要從以下六個方面來進行:
- 現狀(業務背景和技術背景)
- 需求(業務需求和效能需求)
- 方案描述(概要、詳細說明、效能評估、方案優缺點)
- 方案對比,介紹不同方案的突出點,並做出傾向選擇和選擇理由
- 風險評估
- 工作量評估
3.4 效能和容量評估經典案例
通過介紹下單時需要的收貨地址和物流資訊的需求,計算每次請求的量和資料儲存以及讀取速度等,給出了系統應用層伺服器、資料庫、快取、訊息佇列的最大化方案和最小化方案,也說明了初期可以採用從最小化方案的好處以及可以配置的開關等。
3.5 效能評估參考標準
主要介紹了系統層效能指標和應用層的效能指標,當需要時可以參考指標進行合理的輸出。
3.6 效能測試的方案設計與最佳實踐
壓力測試執行步驟:
1. 確定壓測目標。
2. 壓測場景設計和壓測方案制定
3. 準備測壓環境
4. 壓測的執行
5. 問題修復和系統優化
3.7 有用的壓測工具
- ab
- jmeter
- mysqlslap
- sysbench
- dd
- LoadRunner
- hprof
總結
網際網路時代對系統的非功能質量有很高的要求,本章主要就非功能質量的需求做出了相對詳細的說明和實踐。也列舉了我們進行技術評審、效能方案評估、壓測流程和相關壓測工具的說明例項。
4. 大資料日誌系統的構建
日誌對於我們來說非常重要,日誌根據來源、目標、級別又可以分為很多不同的型別。我們主要常用的有:業務系統應用日誌、效能日誌、服務遠端呼叫日誌等。在使用日誌時,我們需要確定好怎麼輸出日誌和怎麼儲存日誌,最後才是怎麼使用日誌。
4.1 開源日誌框架的原理分析和應用實踐
講解了日誌框架的逐步升級。從JDK提供的Jdk Logger 到apache提供的Commons Logger,再到apache log4j,再此基礎上又進一步改良用非同步載入日誌方式提升效能使用的Slf4j和Logback,最後到目前結合了Slf4j和Logback的優秀特性的Slf4j2。採用Disrupter的無鎖特性,提升了日誌的記錄效能。
4.2 日誌系統的優化與最佳實踐
- 開發任務要養成日誌記錄的習慣;
- 日誌級別的設定,線上環境和測試環境等需要有不同的日誌級別;
- 日誌數量和大小,我們需要在關鍵路徑上設定日誌,並且日誌的大小要儘可能的小,但要全;
- 日誌的分割,儘量使用日誌框架原生的滾動追加方式;
- 日誌的格式,注意的是使用‘ %L ’的情況,可能對系統性能有一定的影響。
4.3 大資料日誌系統的架構與設計
大資料日誌系統一般我們在每臺伺服器上新增日誌採集器,通過採集器監控日誌,如果產生日誌則將日誌檔案存入到緩衝佇列,通過日誌解析器進行解析,一般我們將資料解析成JSON格式的資料後儲存到有序的儲存系統中並簡歷索引。
- 日誌採集器目前最流行的是Logstash和fluentd。都廣泛的被社群和開發者使用,兩者在處理效能上沒有很大的差別。
- 日誌緩衝佇列,我們通常採用的訊息佇列比如Kafka、redis、RabbitMq等。推薦使用效能最好的Kafka。
- 日誌解析器,可以才用Logstash和Fluentd當做解析器,也可以使用更加專業storm和spark作為解析器。
- 日誌儲存和搜尋引擎,一般採用比較常規和好用的Elasticsearch和Solr等。注意對日誌要做定期的清理。
- 日誌的展示系統,一般在自身的伺服器或者手機APP上建立體統的展示。
- 監控和報警,日誌儲存到系統和搜尋引擎中我們可以簡歷監控和報警系統,保證服務的穩定執行。
- 日誌系統的容量和效能評估,可以根據第三節的知識點計算相應的峰值等引數資訊進行儲存裝置和服務引擎等的配置。
4.4 ELK系統的構建與設計
Elk 系統主要由三大模組組成:Elasticsearch、Logstash、Kibana。這裡只是簡單的講解了三個框架的使用,我們再具體使用時還需要自己不斷深入。
總結
我們做微服務要注重日誌的記錄,有了日誌不僅可以快速定位問題的所在,也可以根據日誌進行服務監測和資料分析,我們一般系統常用的slf4j2等高效能框架可以簡單的提供一系列日誌,但是在分散式服務的情況下,搭建一個高效能高可用的大資料日誌系統是非常有必要的,我們可以採用ELK的日誌框架模式構建自身系統相符的日誌系統。
5. 基於呼叫鏈的服務治理系統設計與實現
- 我們在做了常規的日誌系統以後,往往還要面臨線上突發緊急情況的處理,這個時候去一個個排場系統會顯得特別麻煩,因此,我們通常會使用APM(應用效能服務)系統進行監控。目前比較流行的開源APM系統主要有:Pinpoint、Zipkin、CAT。商用版本的系統有:聽雲、博睿、oneAPM、雲智慧。
- 對於呼叫鏈最早出現在谷歌的Dapper論文上,它提出在應用層增加標記來對服務化中的請求和響應建立聯絡。我們一般採用在HTTP請求頭中設定標記資訊:系統呼叫的全域性流水ID(traceID)、服務節點的spanID與parentSpanID,通過他們構成一條業務鏈上的標記。
- 呼叫鏈的設計和實現與我們設定日誌系統沒有太大的區別,只是我們在訊息進行採集和處理時需要新增標識資訊。
6.java服務的線上應急和技術攻關
- 線上的急性問題我們需要有一下原則:
- 第一時間回覆系統我不是徹底解決,達到快速止損;
- 有明顯的資金損失時,第一時間升級系統,達到快速止損;
- 應急指揮圍繞應急目標啟動應急流程和快速止損方案;
- 不能短時間解決問題,進行升級處理;
- 在不影響使用者體驗的前提下,保留部分現場和資料。
- 分析問題從以下幾個方面考慮:
- 問題系統最近是否進行了上線;
- 依賴的資源或基礎平臺最近是否進行了升級或上線;
- 依賴的系統是否進行了上線;
- 運營是否在系統裡面做過運營變更;
- 網路是否有波動;
- 最近的業務是否上量;
- 服務的使用方是否有促銷活動等。