主頁 > 後端開發 > 面試 | 分布式問題在怎么問,都跑不了這些內容

面試 | 分布式問題在怎么問,都跑不了這些內容

2020-12-06 06:10:17 後端開發

1.問題

  • 1、何為分布式何為微服務?
  • 2、為什么需要分布式?
  • 3、分布式核心理論基礎,節點、網路、時間、順序,一致性?
  • 4、分布式是系統有哪些設計模式?
  • 5、分布式有哪些型別?
  • 6、如何實作分布式?

2.關鍵詞

節點,時間,一致性,CAP,ACID,BASE,P2P,機器伸縮,網路變更,負載均衡,限流,鑒權,服務發現,服務編排,降級,熔斷,冪等,分庫分表,分片磁區,自動運維,容錯處理,全堆疊監控,故障恢復,性能調優

3.全文概要

隨著移動互聯網的發展智能終端的普及,計算機系統早就從單機獨立作業過渡到多機器協作作業,計算機以集群的方式存在,按照分布式理論的指導構建出龐大復雜的應用服務,也已經深入人心,本文力求從分布式基礎理論,架構設計模式,工程應用,部署運維,業界方案這幾大方面,介紹基于MSA(微服務架構)的分布式的知識體系大綱,從而對SOA到MSA進化有個立體的認識,從概念上和工具應用上更近一步了解微服務分布式的本質,身臨其境的感受如何搭建全套微服務架構的程序,

4.基礎理論

4.1SOA到MSA的進化

SOA面向服務架構

由于業務發展到一定層度后,需要對服務進行解耦,進而把一個單一的大系統按邏輯拆分成不同的子系統,通過服務介面來通訊,面向服務的設計模式,最終需要總線集成服務,而且大部分時候還共享資料庫,出現單點故障的時候會導致總線層面的故障,更進一步可能會把資料庫拖垮,所以才有了更加獨立的設計方案的出現,

file

MSA微服務架構

微服務是真正意義上的獨立服務,從服務入口到資料持久層,邏輯上都是獨立隔離的,無需服務總線來接入,但同時增加了整個分布式系統的搭建和管理難度,需要對服務進行編排和管理,所以伴隨著微服務的興起,微服務生態的整套技術堆疊也需要無縫接入,才能支撐起微服務的治理理念,

file

4.2節點與網路

節點

傳統的節點也就是一臺單體的物理機,所有的服務都揉進去包括服務和資料庫;隨著虛擬化的發展,單臺物理機往往可以分成多臺虛擬機,實作資源利用的最大化,節點的概念也變成單臺虛擬機上面服務;近幾年容器技術逐漸成熟后,服務已經徹底容器化,也就是節點只是輕量級的容器服務,總體來說,節點就是能提供單位服務的邏輯計算資源的集合,

網路

分布式架構的根基就是網路,不管是局域網還是公網,沒有網路就無法把計算機聯合在一起作業,但是網路也帶來了一系列的問題,網路訊息的傳播有先后,訊息丟失和延遲是經常發生的事情,我們定義了三種網路作業模式:

同步網路

  • 節點同步執行
  • 訊息延遲有限
  • 高效全域鎖

半同步網路

  • 鎖范圍放寬

異步網路

  • 節點獨立執行

  • 訊息延遲無上限

  • 無全域鎖

  • 部分演算法不可行

    常用網路傳輸層有兩大協議的特點簡介:

TCP協議

  • 首先tcp盡管其他可以更快
  • tcp解決重復和亂序問題

UDP協議

  • 常量資料流
  • 丟包不致命

4.3時間與順序

時間

慢速物理時空中,時間獨自在流淌著,對于串行的事務來說,很簡單的就是跟著時間的腳步走就可以,先來后到的發生,而后我們發明了時鐘來刻畫以往發生的時間點,時鐘讓這個世界盡然有序,但是對于分布式世界來說,跟時間打交道著實是一件痛苦的事情,分布式世界里面,我們要協調不同節點之間的先來后到關系,但是不同節點本身承認的時間又各執己見,于是我們創造了網路時間協議(NTP)試圖來解決不同節點之間的標準時間,但是NTP本身表現并不如人意,所以我們又構造除了邏輯時鐘,最后改進為向量時鐘:

NTP的一些缺點,無法完全滿足分布式下并發任務的協調問題

  • 節點間時間不同步
  • 硬體時鐘漂移
  • 執行緒可能休眠
  • 作業系統休眠
  • 硬體休眠

file

邏輯時鐘

  • 定義事件先來后到

  • t’ = max(t, t_msg + 1)

file

向量時鐘

  • t_i’ = max(t_i, t_msg_i)

原子鐘

順序

有了衡量時間的工具,解決順序問題自然就是水到渠成了,因為整個分布式的理論基礎就是如何協商不同節點的一致性問題,而順序則是一致性理論的基本概念,所以前文我們才需要花時間介紹衡量時間的刻度和工具,

4.4一致性理論

說到一致性理論,我們必須看一張關于一致性強弱對系統建設影響的對比圖:

file
該圖對比了不同一致性演算法下的事務,性能,錯誤,延遲的平衡,

強一致性ACID

單機環境下我們對傳統關系型資料庫有苛刻的要求,由于存在網路的延遲和訊息丟失,ACID便是保證事務的原則,這四大原則甚至我們都不需要解釋出來就耳熟能詳了:

  • Atomicity:原子性,一個事務中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節,
  • Consistency:一致性,在事務開始之前和事務結束以后,資料庫的完整性沒有被破壞,
  • Isolation:隔離性,資料庫允許多個并發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致資料的不一致,
  • Durabilit:事務處理結束后,對資料的修改就是永久的,即便系統故障也不會丟失,

分布式一致性CAP

分布式環境下,我們無法保證網路的正常連接和資訊的傳送,于是發展出了CAP/FLP/DLS這三個重要的理論:

  • CAP:分布式計算系統不可能同時確保一致性(Consistency)、可用性(Availablity)和磁區容忍性(Partition),

  • FLP:在異步環境中,如果節點間的網路延遲沒有上限,只要有一個惡意的節點存在,就沒有演算法能在有限的時間內達成共識,

  • DLS:

    (1)在一個部分同步網路的模型(也就是說:網路延時有界限但是我們并不知道在哪里)下運行的協議可以容忍1/3任意(換句話說,拜占庭)錯誤;

    (2)在一個異步模型中的確定性的協議(沒有網路延時上限)不能容錯(不過這個論文沒有提起隨機化演算法可以容忍1/3的錯誤);

    (3)同步模型中的協議(網路延時可以保證小于已知d時間)可以,令人吃驚的,達到100%容錯,雖然對1/2的節點出錯可以發生的情況有所限制

弱一致性BASE

多數情況下,其實我們也并非一定要求強一致性,部分業務可以容忍一定程度的延遲一致,所以為了兼顧效率,發展出來了最終一致性理論BASE,BASE是指基本可用(Basically Available)、軟狀態( Soft State)、最終一致性( Eventual Consistency)

  • 基本可用(Basically Available):基本可用是指分布式系統在出現故障的時候,允許損失部分可用性,即保證核心可用,
  • 軟狀態(Soft State):軟狀態是指允許系統存在中間狀態,而該中間狀態不會影響系統整體可用性,分布式存盤中一般一份資料至少會有三個副本,允許不同節點間副本同步的延時就是軟狀態的體現,
  • 最終一致性(Eventual Consistency):最終一致性是指系統中的所有資料副本經過一定時間后,最終能夠達到一致的狀態,弱一致性和強一致性相反,最終一致性是弱一致性的一種特殊情況,

一致性演算法

分布式架構的核心就在一致性的實作和妥協,那么如何設計一套演算法來保證不同節點之間的通信和資料達到無限趨向一致性,就非常重要了,保證不同節點在充滿不確定性網路環境下能達成相同副本的一致性是非常困難的,業界對該課題也做了大量的研究,

首先我們要了解一致性的大前提*原則*(CALM):

CALM原則的全稱是 Consistency and Logical Monotonicity ,主要描述的是分布式系統中單調邏輯與一致性的關系,它的內容如下,參考consistency as logical monotonicity

  • 在分布式系統中,單調的邏輯都能保證 “最終一致性”,這個程序中不需要依賴中心節點的調度
  • 任意分布式系統,如果所有的非單調邏輯都有中心節點調度,那么這個分布式系統就可以實作最終“一致性”

然后再關注分布式系統的*資料結構*CRDT(Conflict-Free Replicated Data Types):

我們了解到分布式一些規律原則之后,就要著手考慮如何來實作解決方案,一致性演算法的前提是資料結構,或者說一切演算法的根基都是資料結構,設計良好的資料結構加上精妙的演算法可以高效的解決現實的問題,經過前人不斷的探索,我們得知分布式系統被廣泛采用的資料結構CRDT,

參考《談談CRDT》,A comprehensive study of Convergent and Commutative Replicated Data Types

  • 基于狀態(state-based):即將各個節點之間的CRDT資料直接進行合并,所有節點都能最終合并到同一個狀態,資料合并的順序不會影響到最終的結果,
  • 基于操作(operation-based):將每一次對資料的操作通知給其他節點,只要節點知道了對資料的所有操作(收到操作的順序可以是任意的),就能合并到同一個狀態,

了解資料結構后,我們需要來關注一下分布式系統的一些重要的*協議*HATs(Highly Available Transactions),ZAB(Zookeeper Atomic Broadcast):

參考《高可用事務》,《ZAB協議分析》

最后要學習的是業界主流的一致性*演算法*

說實話具體的演算法我也還沒完全搞懂,一致性演算法是分布式系統最核心本質的內容,這部分的發展也會影響架構的革新,不同場景的應用也催生不同的演算法

  • Paxos:《優雅的Paxos演算法》
  • Raft :《Raft 一致性演算法》
  • Gossip:《Gossip Visualization》

這一節我們說完分布式系統里面核心理論基礎,如何達成不同節點之間的資料一致性,下面我們將會講到目前都有哪些主流的分布式系統,

5.場景分類

5.1檔案系統

單臺計算機的存盤始終有上限,隨著網路的出現,多臺計算機協作存盤檔案的方案也相繼被提出來,最早的分布式檔案系統其實也稱為網路檔案系統,第一個檔案服務器在1970年代被發展出來,在1976年迪吉多公司設計出File Access Listener(FAL),而現代分布式檔案系統則出自赫赫有名的Google的論文,《The Google File System》奠定了分布式檔案系統的基礎,現代主流分布式檔案系統參考《分布式檔案系統對比》,下面列舉幾個常用的檔案系統

  • HDFS
  • FastDFS
  • Ceph
  • mooseFS

5.2資料庫

資料庫當然也是屬于檔案系統,主資料增加了事務,檢索,擦除等高級特性,所以復雜度又增加了,既要考慮資料一致性也得保證足夠的性能,傳統關系型資料庫為了兼顧事務和性能的特性,在分布式方面的發展有限,非關系型資料庫擺脫了事務的強一致性束縛,達到了最終一致性的效果,從而有了飛躍的發展,NoSql(Not Only Sql)也產生了多個架構的資料庫型別,包括KV,列式存盤,檔案型別等,

  • 列式存盤:Hbase
  • 檔案存盤:Elasticsearch,MongoDB
  • KV型別:Redis
  • 關系型:Spanner

5.3計算

分布式計算系統構建在分布式存盤的基礎上,充分發揮分布式系統的資料冗余災備,多副本高效獲取資料的特性,進而并行計算,把原本需要長時間計算的任務拆分成多個任務并行處理,從而提高了計算效率,分布式計算系統在場景上分為離線計算,實時計算和流式計算,

  • 離線:Hadoop
  • 實時:Spark
  • 流式:Storm,Flink/Blink

5.4快取

快取作為提升性能的利器無處不在,小到CPU快取架構,大道分布式應用存盤,分布式快取系統提供了熱點資料的隨機訪問機制,大大了提升了訪問時間,但是帶來的問題是如何保證資料的一致性,引入分布式鎖來解決這個問題,主流的分布式存盤系統基本就是Redis了

  • 持久化:Redis
  • 非持久化:Memcache

5.5訊息

分布式訊息佇列系統是消除異步帶來一系列的復雜步驟的一大利器,多執行緒高并發場景先我們常常要謹慎的去設計業務代碼,來保證多執行緒并發情況下不出現資源競爭導致的死鎖問題,而訊息佇列以一種延遲消費的模式將異步任務都存到佇列,然后再逐個消化,

  • Kafka
  • RabbitMQ
  • RocketMQ
  • ActiveMQ

5.6監控

分布式系統從單機到集群的形態發展,復雜度也大大提高,所以對整個系統的監控也是必不可少,

  • Zookeeper

5.7應用

分布式系統的核心模塊就是在應用如何處理業務邏輯,應用直接的呼叫依賴于特定的協議來通信,有基于RPC協議的也有基于通用的HTTP協議,

  • HSF
  • Dubble

5.8日志

錯誤對應分布式系統是家常便飯,而且我們設計系統的時候本身就需要把容錯作為普遍存在的現象來考慮,那么當出現故障的時候,快速恢復和排查故障就顯得非常重要了,分布式日志采集存盤和檢索則可以給我提供有力的工具來定位請求鏈路中出現問題的環節,

  • 日志采集:flume
  • 日志存盤:ElasticSearch/Solr,SLS
  • 日志定位:Zipkin

5.9賬本

前文我們提到所謂分布式系統,是迫于單機的性能有限,而堆硬體卻又無法無休止的增加,單機堆硬體最終也會遇到性能增長曲線的瓶頸,于是我們才采用了多臺計算機來干同樣的活,但是這樣的分布式系統始終需要中心化的節點來監控或者調度系統的資源,即使該中心節點也可能是多節點組成,而區塊鏈則是真正的區中心化分布式系統,系統里面才有P2P網路協議各自通信,沒有真正意義的中心節點,彼此按照區塊鏈節點的算力,權益等機制來協調新區塊的產生,

  • 位元幣
  • 以太坊

6.設計模式

上節我們列舉了不同場景下不同分布式系統架構扮演的角色和實作的功能,本節我們更進一步歸納分布式系統設計的時候是如何考慮架構設計的,不同設計方案直接的區別和側重點,不同場景需要選擇合作設計模式,來減少試錯的成本,設計分布式系統需要考慮以下的問題,

6.1可用性

可用性是系統運行和作業的時間比例,通常以正常運行時間的百分比來衡量,它可能受系統錯誤,基礎架構問題,惡意攻擊和系統負載的影響,分布式系統通常為用戶提供服務級別協議(SLA),因此應用程式必須設計為最大化可用性,

  • 健康檢查:系統實作全鏈路功能檢查,外部工具定期通過公開端點訪問系統
  • 負載均衡:使用佇列起到削峰作用,作為請求和服務之間的緩沖區,以平滑間歇性的重負載
  • 節流:限制應用級別、租戶或整個服務所消耗資源的范圍

6.2資料管理

資料管理是分布式系統的關鍵要素,并影響大多數質量的屬性,由于性能,可擴展性或可用性等原因,資料通常托管在不同位置和多個服務器上,這可能帶來一系列挑戰,例如,必須維護資料一致性,并且通常需要跨不同位置同步資料,

  • 快取:根據需要將資料從資料存盤層加載到快取
  • CQRS(Command Query Responsibility Segregation): 命令查詢職責分離
  • 事件溯源:僅使用追加方式記錄域中完整的系列事件
  • 索引表:在經常查詢參考的欄位上創建索引
  • 物化視圖:生成一個或多個資料預填充視圖
  • 拆分:將資料拆分為水平的磁區或分片

6.3設計與實作

良好的設計包括諸如組件設計和部署的一致性,簡化管理和開發的可維護性,以及允許組件和子系統用于其他應用程式和其他方案的可重用性等因素,在設計和實施階段做出的決策對分布式系統和服務質量和總體擁有成本產生巨大影響,

  • 代理:反向代理
  • 配接器: 在現代應用程式和遺留系統之間實作配接器層
  • 前后端分離: 后端服務提供介面供前端應用程式呼叫
  • 計算資源整合:將多個相關任務或操作合并到一個計算單元中
  • 配置分離:將配置資訊從應用程式部署包中移出到配置中心
  • 網關聚合:使用網關將多個單獨的請求聚合到一個請求中
  • 網關卸載:將共享或專用服務功能卸載到網關代理
  • 網關路由:使用單個端點將請求路由到多個服務
  • 領匯入選舉:通過選擇一個實體作為負責管理其他實體管理員,協調分布式系統的云
  • 管道和過濾器:將復雜的任務分解為一系列可以重復使用的單獨組件
  • 邊車:將應用的監控組件部署到單獨的行程或容器中,以提供隔離和封裝
  • 靜態內容托管:將靜態內容部署到CDN,加速訪問效率

6.4訊息

分布式系統需要一個連接組件和服務的訊息傳遞中間件,理想情況是以松散耦合的方式,以便最大限度地提高可伸縮性,異步訊息傳遞被廣泛使用,并提供許多好處,但也帶來了諸如訊息排序,冪等性等挑戰

  • 競爭消費者:多執行緒并發消費
  • 優先級佇列: 訊息佇列分優先級,優先級高的先被消費

6.5管理與監控

分布式系統在遠程資料中心中運行,無法完全控制基礎結構,這使管理和監視比單機部署更困難,應用必須公開運行時信息,管理員可以使用這些資訊來管理和監視系統,以及支持不斷變化的業務需求和自定義,而無需停止或重新部署應用,

6.6性能與擴展

性能表示系統在給定時間間隔內執行任何操作的回應性,而可伸縮性是系統處理負載增加而不影響性能或容易增加可用資源的能力,分布式系統通常會遇到變化的負載和活動高峰,特別是在多租戶場景中,幾乎是不可能預測的,相反,應用應該能夠在限制范圍內擴展以滿足需求高峰,并在需求減少時進行擴展,可伸縮性不僅涉及計算實體,還涉及其他元素,如資料存盤,訊息佇列等,

6.7彈性

彈性是指系統能夠優雅地處理故障并從故障中恢復,分布式系統通常是多租戶,使用共享平臺服務,競爭資源和帶寬,通過Internet進行通信,以及在商用硬體上運行,意味著出現瞬態和更永久性故障的可能性增加,為了保持彈性,必須快速有效地檢測故障并進行恢復,

  • 隔離:將應用程式的元素隔離到池中,以便在其中一個失敗時,其他元素將繼續運行,
  • 斷路器:處理連接到遠程服務或資源時可能需要不同時間修復的故障,
  • 補償交易:撤消一系列步驟執行的作業,這些步驟共同定義最終一致的操作
  • 健康檢查:系統實作全鏈路功能檢查,外部工具定期通過公開端點訪問系統
  • 重試:通過透明地重試先前失敗的操作,使應用程式在嘗試連接到服務或網路資源時處理預期的臨時故障

6.8安全

安全性是系統能夠防止在設計使用之外的惡意或意外行為,并防止泄露或丟失資訊,分布式系統在受信任的本地邊界之外的Internet上運行,通常向公眾開放,并且可以為不受信任的用戶提供服務,必須以保護應用程式免受惡意攻擊,限制僅允許對已批準用戶的訪問,并保護敏感資料,

  • 聯合身份:將身份驗證委派給外部身份提供商
  • 看門人: 通過使用專用主機實體來保護應用程式和服務,該實體充當客戶端與應用程式或服務之間的代理,驗證和清理請求,并在它們之間傳遞請求和資料
  • 代客鑰匙:使用為客戶端提供對特定資源或服務的受限直接訪問的令牌或密鑰,

7.工程應用

前文我們介紹了分布式系統的核心理論,面臨的一些難題和解決問題的折中思路,羅列了現有主流分布式系統的分類,而且歸納了建設分布式系統的一些方法論,那么接下來我們將從工程角度來介紹真刀真槍搭建分布式系統包含的內容和步驟,

7.1資源調度

巧婦難為無米之炊,我們一切的軟體系統都是構建在硬體服務器的基礎上,從最開始的物理機直接部署軟體系統,到虛擬機的應用,最后到了資源上云容器化,硬體資源的使用也開始了集約化的管理,本節從對比的是傳統運維角色對應的職責范圍,在devops環境下,開發運維一體化,我們要實作的也是資源的靈活高效使用,

彈性伸縮

過去軟體系統隨著用戶量增加需要增加機器資源的話,傳統的方式就是找運維申請機器,然后部署好軟體服務接入集群,整個程序依賴的是運維人員的人肉經驗,效率低下而且容易出錯,微服務分布式則無需人肉增加物理機器,在容器化技術的支撐下,我們只需要申請云資源,然后執行容器腳本即可,

  • 應用擴容

    用戶激增需要對服務進行擴展,包括自動化擴容,峰值過后的自動縮容

  • 機器下線

    對于過時應用,進行應用下線,云平臺識訓容器宿主資源

  • 機器置換

    對于故障機器,可供置換容器宿主資源,服務自動啟動,無縫切換

網路管理

有了計算資源后,另外最重要的就是網路資源了,在現有的云化背景下,我們幾乎不會直接接觸到物理的帶寬資源,而是直接的由云平臺統一管理帶寬資源,我們需要的是對網路資源的最大化應用和有效的管理,

  • 域名申請

    應用申請配套域名資源的申請,多套域名映射規則的規范

  • 域名變更

    域名變更統一平臺管理

  • 負載管理

    多機應用的訪問策略設定

  • 安全外聯

    基礎訪問鑒權,攔截非法請求

  • 統一接入

    提供統一接入的權限申請平臺,提供統一的登錄管理

故障快照

在系統故障的時候我們第一要務是系統恢復,同時保留案發現場也是非常重要的,資源調度平臺則需要有統一的機制保存好故障現場,

  • 現場保留

    記憶體分布,執行緒數等資源現象的保存,如JavaDump鉤子接入

  • 除錯接入

    采用位元組碼技術無需入侵業務代碼,可以供生產環境現場日志打點除錯

7.2流量調度

在我們建設好分布式系統后,最先受到考驗的關口就是網關了,進而我們需要關注好系統流量的情況,也就是如何對流量的管理,我們追求的是在系統可容納的流量上限內,把資源留給最優質的流量使用,而把非法惡意的流量擋在門外,這樣節省成本的同時確保系統不會被沖擊崩潰,

負載均衡

負載均衡是我們對服務如何消化流量的通用設計,通常分為物理層的底層協議分流的硬負載均衡和軟體層的軟負載,負載均衡解決方案已經是業界成熟的方案,我們通常會針對特定業務在不同環境進行優化,常用有如下的負載均衡解決方案

  • 交換機
  • F5
  • LVS/ALI-LVS
  • Nginx/Tengine
  • VIPServer/ConfigServer

網關設計

負載均衡首當其沖的就是網關,因為中心化集群流量最先打到的地方就是網關了,如果網關扛不住壓力的話,那么整個系統將不可用,

  • 高性能

    網關設計第一需要考慮的是高性能的流量轉發,網關單節點通常能達到上百萬的并發流量

  • 分布式

    出于流量壓力分擔和災備考慮,網關設計同樣需要分布式

  • 業務篩選

    網關同設計簡單的規則,排除掉大部分的惡意流量

流量管理

  • 請求校驗

    請求鑒權可以把多少非法請求攔截,清洗

  • 資料快取

    多數無狀態的請求存在資料熱點,所以采用CDN可以把相當大一部分的流量消費掉

流控控制

剩下的真實流量我們采用不同的演算法來分流請求

  • 流量分配

    • 計數器
    • 佇列
    • 漏斗
    • 令牌桶
    • 動態流控
  • 流量限制

    在流量激增的時候,通常我們需要有限流措施來防止系統出現雪崩,那么就需要預估系統的流量上限,然后設定好上限數,但流量增加到一定閾值后,多出來的流量則不會進入系統,通過犧牲部分流量來保全系統的可用性,

    • QPS粒度
    • 執行緒數粒度
    • RT閾值
    • 限流策略
    • 限流工具 - Sentinel

7.3服務調度

所謂打鐵還需自身硬,流量做好了調度管理后,剩下的就是服務自身的健壯性了,分布式系統服務出現故障是常有的事情,甚至我們需要把故障本身當做是分布式服務的一部分,

注冊中心

我們網路管理一節中介紹了網關,網關是流量的集散地,而注冊中心則是服務的根據地,

  • 狀態型別

    第一好應用服務的狀態,通過注冊中心就可以檢測服務是否可用

  • 生命周期

    應用服務不同的狀態組成了應用的生命周期

版本管理

  • 集群版本

    集群不用應用有自身對應的版本號,由不同服務組成的集群也需要定義大的版本號

  • 版本回滾

    在部署例外的時候可以根據大的集群版本進行回滾管理

服務編排

服務編排的定義是:通過訊息的互動序列來控制各個部分資源的互動,參與互動的資源都是對等的,沒有集中的控制,微服務環境下服務眾多我們需要有一個總的協調器來協議服務之間的依賴,呼叫關系,K8S則是我們的不二選擇,

  • K8S

  • Spring Cloud

    • HSF
    • ZK+Dubble

服務控制

前面我們解決了網路的健壯性和效率問題,這節介紹的是如何使我們的服務更加健壯,

  • 發現

    資源管理那節我們介紹了從云平臺申請了容器宿主資源后,通過自動化腳本就可以啟動應用服務,啟動后服務則需要發現注冊中心,并且把自身的服務資訊注冊到服務網關,也即是網關接入,注冊中心則會監控服務的不同狀態,做健康檢查,把不可用的服務歸類標記,

    • 網關接入
    • 健康檢查
  • 降級

    當用戶激增的時候,我們首先是在流量端做手腳,也就是限流,當我們發現限流后系統回應變慢了,有可能導致更多的問題時,我們也需要對服務本身做一些操作,服務降級就是把當前不是很核心的功能關閉掉,或者不是很要緊的準確性放寬范圍,事后再做一些人工補救,

    • 降低一致性約束
    • 關閉非核心服務
    • 簡化功能
  • 熔斷

    當我們都做了以上的操作后,還是覺得不放心,那么就需要再進一步操心,熔斷是對過載的一種自身保護,猶如我們開關跳閘一樣,比如當我們服務不斷對資料庫進行查詢的時候,如果業務問題造成查詢問題,這是資料庫本身需要熔斷來保證不會被應用拖垮,并且訪問友好的資訊,告訴服務不要再盲目呼叫了,

    • 閉合狀態
    • 半開狀態
    • 斷開狀態
    • 熔斷工具- Hystrix
  • 冪等

    我們知道,一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同,那么久需要對單次操作賦予一個全域的id來做標識,這樣多次請求后我們可以判斷來源于同個客戶端,避免出現臟資料,

    • 全域一致性ID
    • Snowflake

7.4資料調度

資料存盤最大的挑戰就是資料冗余的管理,冗余多了效率變低而且占用資源,副本少了起不到災備的作用,我們通常的做法是把有轉態的請求,通過轉態分離,轉化為無狀態請求,

狀態轉移

分離狀態至全域存盤,請求轉換為無狀態流量,比如我們通常會將登陸資訊快取至全域redis中間件,而不需要在多個應用中去冗余用戶的登陸資料,

分庫分表

資料橫向擴展

分片磁區

多副本冗余

7.5自動化運維

我們從資源申請管理的時候就介紹到devops的趨勢,真正做到開發運維一體化則需要不同的中間件來配合完成,

配置中心

全域配置中心按環境來區分,統一管理,減少了多處配置的混亂局面

  • switch
  • diamend

部署策略

微服務分布式部署是家常便飯,如何讓我們的服務更好的支撐業務發展,穩健的部署策略是我們首先需要考慮的,如下的部署策略適合不同業務和不同的階段,

  • 停機部署
  • 滾動部署
  • 藍綠部署
  • 灰度部署
  • A/B測驗

作業調度

任務調度是系統必不可少的一個環節,傳統的方式是在Linux機器上配置crond定時任務或者直接在業務代碼里面完成調度業務,現在則是成熟的中間件來代替,

  • SchedulerX
  • Spring定時任務

應用管理

運維作業中很大一部分時間需要對應用進行重啟,上下線操作,還有日志清理,

  • 應用重啟
  • 應用下線
  • 日志清理

7.6容錯處理

既然我們知道分布式系統故障時家常便飯的事情,那么應對故障的方案也是不可或缺的環節,通常我們有主動和被動的方式來處理,主動是在錯誤出現的時候,我們試圖再試試幾次,說不定就成功了,成功的話就可以避免了該次錯誤,被動方式是錯誤的事情已經發生了,為了挽回,我們只是做時候處理,把負面影響降到最小,

重試設計

重試設計的關鍵在于設計好重試的時間和次數,如果超過重試次數,或是一段時間,那么重試就沒有意義了,開源的專案 spring-retry可以很好的實作我們重試的計劃,

事務補償

事務補償符合我們最終一致性的理念,補償事務不一定會將系統中的資料回傳到原始操作開始時其所處的狀態, 相反,它補償操作失敗前由已成功完成的步驟所執行的作業,補償事務中步驟的順序不一定與原始操作中步驟的順序完全相反, 例如,一個資料存盤可能比另一個資料存盤對不一致性更加敏感,因而補償事務中撤銷對此存盤的更改的步驟應該會首先發生,對完成操作所需的每個資源采用短期的基于超時的鎖并預先獲取這些資源,這樣有助于增加總體活動成功的可能性, 僅在獲取所有資源后才應執行作業, 鎖過期之前必須完成所有操作,

7.7全堆疊監控

由于分布式系統是由眾多機器共同協作的系統,而且網路也無法保證完全可用,所以我們需要建設一套對各個環節都能監控的系統,這樣我們才能從底層到業務各個層面進行監控,出現意外的時候可以及時修復故障,避免更多的問題出現,

基礎層

基礎層面是對容器資源的監測,包含各個硬體指標的負載情況

  • CPU,IO,記憶體,執行緒,吞吐

中間件

分布式系統接入了大量的中間件平臺,中間件本身的健康情況也需要監控

應用層

  • 性能監控

    應用層面的需要對每個應用服務的實時指標(qps,rt),上下游依賴等進行監控

  • 業務監控

    除了應用本身的監控程度,業務監控也是保證系統正常的一個環節,通過設計合理的業務規則,對例外的情況做報警設定

監控鏈路

  • zipkin/eagleeye
  • sls
  • goc
  • Alimonitor

7.8故障恢復

當故障已經發生后,我們第一要做的是馬上消除故障,確保系統服務正常可用,這個時候通常的做回滾操作,

應用回滾

應用回滾之前需要保存好故障現場,以便排查原因,

基線回退

應用服務回滾后,代碼基線也需要revert到前一版本,

版本回滾

整體回滾需要服務編排,通過大版本號對集群進行回滾,

7.9性能調優

性能優化是分布式系統的大專題,涉及的面非常廣,這塊簡直可以單獨拿出來做一個系列來講,本節就先不展開,本身我們做服務治理的程序也是在性能的優化程序,

分布式鎖

快取是解決性能問題的一大利器,理想情況下,每個請求不需要額外計算立刻能獲取到結果回傳時最快的,小到CPU的三級快取,大到分布式快取,快取無處不在,分布式快取需要解決的就是資料的一致性,這個時候我們引入了分布式鎖的概念,如何處理分布式鎖的問題將決定我們獲取快取資料的效率,

高并發

多執行緒編程模式提升了系統的吞吐量,但也同時帶來了業務的復雜度,

異步

事件驅動的異步編程是一種新的編程模式,摒棄了多執行緒的復雜業務處理問題,同時能夠提升系統的回應效率,

8.總結

最后總結一下,如果有可能的話,請嘗試使用單節點方式而不是分布式系統,分布式系統伴隨著一些失敗的操作,為了處理災難性故障,我們使用備份,為了提高可靠性,我們引入了冗余,分布式系統本質就是一堆機器的協同,而我們要做的就是搞出各種手段來然機器的運行達到預期,這么復雜的系統,需要了解各個環節,各個中間件的接入,是一個非常大的工程,慶幸的是,在微服務背景下,多數基礎性的作業已經有人幫我們實作了,前文所描述的分布式架構,在工程實作了是需要用到分布式三件套(Docker+K8S+Srping Cloud)基本就可以構建出來了,

分布式架構核心技術分布圖如下:

file

分布式技術堆疊使用中間件:

file

來源:https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&type=10&appmsgid=100006304&token=1487240700&lang=zh_CN

歡迎關注公眾號 【碼農開花】一起學習成長
我會一直分享Java干貨,也會分享免費的學習資料課程和面試寶典
回復:【計算機】【設計模式】【面試】有驚喜哦

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/230516.html

標籤:其他

上一篇:在做分布式快取的時候如何選擇,如何解決遇到的坑?

下一篇:整天都在討論使用SpringBoot,可你居然連快取都不清楚

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more