《持續演進的Cloud Native: 原原生架構下的微服務最佳實踐》
王啟軍/著 (公衆号:奔跑中的蝸牛)
電子工業出版社
2018.10出版
Cloud Native的組成

Cloud Native需要從架構、研發流程和團隊文化三個角度來實作,三者需要互相配合,缺一不可。
-
架構
Cloud Native是以雲和微服務架構為基礎,雲包含了靈活基礎設施及公共基礎元件。同時還需要考慮架構的品質屬性。
-
研發流程
自動化的研發環境是Cloud Native的基礎。盡量減少測試及運維對開發的協助,最好由全棧工程師獨自快速傳遞。
-
團隊文化
一切以人為主,需要建立自由開放的環境。高度信任,增強自我驅動。微服務架構要求小團隊具有自主決策的權力,避免無論大事小事都要拿到會議上讨論,造成決策瓶頸。
Cloud Native成熟度模型
Cloud Native的原則
-
為失敗設計原則
接受出問題是必然的這個現實,架構中能夠容忍故障的發生,最小化故障的影響範圍。
-
不變性原則
每個服務或元件在安裝、部署完成後将不會發生更改,如果更改在丢棄老的部署新的。
-
去中心化原則
不會因為一個節點的故障導緻整個系統不可用,研發流程上做到關注點分離。
-
标準化原則
一旦系統規模變大,做到标準化是無法避免的。所謂獨立自主是在一定的标準下實作。
-
速度優先原則
當速度和效率發生沖突時,速度優先。
-
簡化設計原則
如果你發現設計滿足了所有的要求,說明你一定過度設計了。
-
自動化驅動原則
隻有真正擁抱自動化才能做到持續釋出,才能做到更好的使用者體驗。
-
演進式設計原則
架構是持續演進的,不要一蹴而就。
可用性設計
可用性和可靠性的關系
- 可用性(Availability)是關于系統可以被使用的時間的描述,以丢失的時間為驅動(Be Driven by Lost Time)
- 可靠性(Reliability)是關于系統無失效時間間隔的描述,以發生的失效個數為驅動(Be Driven by Number of Failure)
計算公式
- Availability = Uptime / ( Uptime + Downtime )
-
Reliability = MTBF / (MTBF + MTTR)
MTFB: Mean Time Between Failure 平均無故障工作時間,指上一次故障恢複後開始正常運作到這次故障的時間平均值。
MTTR: Mean Time To Repair 平均故障恢複時間,指從初心故障到完全恢複的這段時間。
可用性的衡量标準
可用性通常以N個9的方式來量化。
可用性等級 | 可用性百分比 | 年度停機時間 | 可能會用到的技術 |
---|---|---|---|
基本可用 | 99% | 87.6小時 | 簡單的負載均衡 |
較高可用 | 99.9% | 8.8小時 | 灰階釋出、自動化釋出、自動化測試、快速復原 |
進階可用 | 99.99% | 53分鐘 | 微服務、中間件自動擴充、容錯、監控、彈性伸縮 |
極高可用 | 99.999% | 5分鐘 | 異地多活、智能運維 |
什麼降低了可用性
- 釋出
- 故障
- 壓力
- 外部強依賴
大型網站典型故障案例
- 寫日志過多
- 高并發通路資料庫
- 緩存故障
- 應用啟動不同步
- 大檔案讀寫獨占磁盤
- 濫用生産環境
- 不規範的流程
- 不好的程式設計習慣
釋出方案
- 影子測試:在生産環境通過流量複制、回放和比對的測試方法。
- 負載均衡日志回放
- TCPCopy
ngx_http_mirror_module、tcpcopy、GoReplay 原名gor、滴滴 rdebug
- A/B Testing: 業務場景并行
-
藍綠部署:系統群并行
在生産環境額外備援一份相同的環境。測試通過後,可用把負載均衡/反向代理/路由從藍色環境指向綠色環境。需要回退直接切整體環境。
-
灰階釋出/金絲雀釋出:部署執行個體新舊版本并行
在原有版本可用的情況下,同時部署一個新的版本作為“金絲雀”,測試新版本的性能和表現,以保證在整體系統穩定的情況下,盡早發現問題并解決問題。
容錯設計
- 消除單點
- 特性開關
- 服務分級
- 降級設計
- 逾時重試
- 隔離政策
- 熔斷器
降級設計
- 關閉功能
- 請求短路
- 簡化流程
- 延遲執行
逾時重試技術考慮點
- 逾時時間
- 重試次數
- 間隔時間
- 間隔時間衰減度
逾時重試技術方案
- 簡單重試模式:try-catch-redo
- 政策重試模式:try-catch-redo-retry strategy
- 基于spring-retry:
- 基于Guava-retrying
服務隔離政策
- 線程池隔離
- 程序隔離
- 叢集隔離
- 使用者隔離
- 租戶隔離
限流算法
- 固定視窗算法 (fixed window)
- 漏桶算法(Leaky Bucket)
- 令牌桶算法(token bucket)
漏桶算法和令牌桶算法的對比
漏桶算法 | 令牌桶算法 |
---|---|
不依賴令牌,不儲存令牌 | 依賴令牌 |
如果桶滿了,則丢棄資料包 | 如果桶滿了,則丢棄令牌,不丢棄資料包 |
不允許突發,恒定速率 | 允許突發 |
限流技術方案
- Guava限流
- Nginx限流
- waf限流
性能設計
常見的性能問題
- 記憶體洩漏:記憶體耗盡
- 過載:突發流量,大量逾時重試
- 網絡瓶頸
- 阻塞:無盡的等待
- 鎖:通過限制
- IO繁忙:大量的讀寫
- CPU繁忙
- 長請求擁塞:連接配接耗盡
性能目标
- 響應時間 latency
- 吞吐量 throughput: QPS
- 負載敏感度
- 可伸縮性
性能目标案例
- 響應時間:99%<1s
- 吞吐量大于10萬TPS
- 系統資料量:10億>訂單表>1億
- 資料增長速度:1億/年
- 資源限制:伺服器、配置、網絡
如何定位瓶頸
- 壓力測試
- 日志分析
- 監控工具
性能優化方向
- 服務通訊優化
- 消息中間件
- 緩存
- 資料庫優化
服務通訊優化
- 同步轉異步
- 阻塞轉非阻塞
- 序列化
可擴充性設計
AKF擴充立方體
描述 | 場景 | 優勢 | 挑戰 | |
---|---|---|---|---|
X軸 | 通常稱為水準擴充,通過複制執行個體,前端對流量進行負載均衡,進而分攤整體壓力 | 産品初期 | 架構簡單,隻需要負載均衡 | 有狀态的服務不容易擴充 |
Y軸 | 根據服務或者資源擴充,即從單體服務演進到微服務架構 | 業務邏輯複雜,代碼規模大 | 故障隔離性好,容易實作業務複雜性分解 | 對工具環境依賴高、運維複雜、一緻性實作成本高 |
Z軸 | 根據查詢或者計算結果進行拆分。即分片 | 大型分布式系統 | 突破單張表的資料規模 | 架構複雜、資料遷移負載 |
微服務的缺點
- 增加了服務調用的開銷
- 分布式系事務
- 調試與服務治理
如何擴
展資料庫
- X軸擴充:主從複制叢集,Master-Slave讀寫分離。
- Y軸擴充:分庫、垂直分表
- X軸擴充:分片(sharding)
- 區間法(Range-Based):一個月一張表
- 輪流法(Round-Robin) :n = K mod N
- 一緻性哈希(Consistent Hash)
一緻性設計
事務之間的關系可以通過happen-before表達為如下四種:
- 讀寫
- 寫讀
- 讀讀
- 寫寫
ANSI SQL92标準定義的四種事務隔離級别如下:
- 未送出讀(Read uncommitted)
- 送出讀(Read committed)
- 可重複讀(Repeatable reads)
- 可串行化(Serializable)
Mysql預設事務隔離級别:可重複讀
隔離級别 | 發生髒讀 | 不可重複讀 | 發生幻讀 | 加鎖讀 |
---|---|---|---|---|
未送出讀 | ✓ | X | ✓ | X |
送出讀 | X | ✓ | ✓ | X |
可重複讀 | X | X | ✓ | X |
可串行化 | X | X | X | ✓ |
分布式事務理論
- Quorum機制
- 租約機制 Lease
- 狀态機 Replilcated state machine
狀态機故障時節點切換算法
- Paxos算法
- Raft算法
Raft算法
Raft算法将Server分為三種類型:Leader、Follower和Candidate。
- Leader處理所有的查詢和事務,并向Follower同步事務。
- Follower會将所有的RPC查詢和事務轉發給Leader處理,它僅從Leader接受事務的同步。資料的一緻性以Leader中的資料為準實作。
Raft把一緻性問題,分解成三個比較獨立的子問題,并給出每個子問題的解決方法:
- 選舉:描述Raft是如何選擇一個leader的,這個部分很受容易了解了。
- 日志複制:描述Raft的leader是如何把日志複制到叢集的各個節點上的。
- 安全性:描述Raft是如何保證“State Machine Safety Property”。
分布式系統的一緻性分類
以資料為中心的一緻性模型
- 嚴格一緻性 strict consistency
- 順序一緻性 sequential consistency
- 因果一緻性 causal consistency
- FIFO一緻性
以使用者為中心的一緻性模型
- 單調讀一緻性 Monotonic-read consistency
- 單調寫一緻性 mono-write consistency
- 寫後讀一緻性 read-your-writes consistency
- 讀後寫一緻性 write-follow-reads consistency
業界常用的一緻性模型
- 弱一緻性
- 最終一緻性 Eventual consistency
- 強一緻性 strong consistency
如何實作強一緻性
- 兩階段送出 2PC
- 三階段送出 3PC
如何實作最終一緻性
- 重試機制
- 本地記錄日志
- 可靠事件模式
- Saga事務模型
- TCC事務模型
分布式鎖
- 基于DBMS: 樂觀鎖CAS,悲觀鎖 select for update
- 基于Zookeeper
- 基于Redis: Set if not exists
如何保證幂等性
- 幂等令牌 Idempotency Key
- 寫前檢查
多版本并發控制(MVCC)