高可用系列文章之一 - 概述 - 東風微鳴技術部落格 (ewhisper.cn)
單點是系統高可用最大的風險和敵人,應該儘量在系統設計的過程中避免單點。
保障系統的高可用, 方法論上,高可用保證的原則是「叢集化」(或 「冗餘」), 只有一個單點,該單點宕機所有服務都會受影響而不可用;如果有冗餘或備份,其中一個點宕機還有其他冗餘或備份節點能夠提供服務。
保證系統高可用,架構設計的核心準則是:冗餘。
有了冗餘之後,還不夠,每次出現故障需要人工介入恢復勢必會增加系統的 MTTR。所以,又往往是通過「自動故障轉移」來實現系統的高可用。
在下面的技術方案中,詳細介紹瞭如何通過冗餘+自動故障轉移來保證系統的高可用特性。
製造業系統一般採用分層架構, 最簡單的典型架構的展示如下:
ℹ️ 備註:
資料庫以 MySQL 為例.
常見的系統架構如上, 分為:
整個系統的高可用, 是通過對每一層的冗餘+自動故障轉移來綜合實現的.
ℹ️ 備註:
通過更加細化和細緻的分層, 也可以提高可用性. 如將以上架構細化為:
- 使用者端層;
- 可選新增: 反向代理層
- 可選新增: 表示層(Web Server)層
- 應用服務層(App Server)層
- 可選新增: 服務呼叫層
- 可選新增: 快取層
- 資料庫層
本文暫不涉及這一內容.
通過冗餘這一核心原則, 優化後的高可用架構如下圖所示:
ℹ️ 說明:
- 實線 : 請求呼叫
- 點+橫線: 心跳檢測
- 點虛線: 尚未真實發生的請求呼叫
- 短橫虛線: 資料庫主從同步
- "X" - 對應節點宕機不可用.
高可用方案調整說明如下:
ℹ️ 備註:
上圖中, 也畫出了高可用的另一種實施方案, 本文不做詳細討論:
- 應用橫向拆分: 單體應用(monolithic application)根據重要性進行拆分, 將重要性高的服務和重要性低的服務進行拆分, 單獨部署.
- 重要性高的應用, 如低延遲類應用, 流水線上應用等;
- 重要性低的應用, 如高延遲類應用, 報表應用等.
除此之外, 還可以根據實際業務情況進一步將資料庫進行拆分, 本文亦不做詳細討論:
- 資料庫拆為 2 個庫, 其中一個庫通過資料同步從另一個庫定時(實時或非實時)同步資料. 舉例說明: 業務庫, 報表庫. (業務庫定期同步資料給報表庫)
- 重要性高的應用, 讀取寫入業務庫;
- 重要性低的應用. 如報表類應用. 不允許使用業務庫, 而是使用報表庫.
下面逐一進行分層論述.
使用者端層 到 負載均衡層 高可用, 通過負載均衡層的冗餘來實現的. 具體實現方式如下:
至少有 2 臺 nginx, 其中一臺提供服務, 另一臺冗餘以保證高可用. 並通過 Keepalived 的 virtual IP 來提供同一 IP(如上圖為: 1.2.5.6), 通過心跳探測來進行故障檢測和故障轉移.
在上圖中, NGINX 主節點提供對外服務.
當 NGINX 主節點(如: 192.168.0.1)發生宕機, Keepalived 能夠探測到, 會自動進行故障轉移, 將流量自動轉移到 NGINX 從節點(如: 192.168.0.2). 由於使用的是相同的 virtual IP(仍為: 1.2.5.6), 這個切換過程對呼叫方是透明的.
負載均衡層 到 應用服務層 的高可用, 是通過應用服務層的冗餘來實現的. 在NGINX的組態檔 nginx.conf
中, 可以通過 upstream
指令設定多個應用伺服器, 並且 nginx 能夠探測到多個應用伺服器的存活性.
ℹ️ 知識點:
在 NGINX 開源版本中, 如果不使用第三方外掛,NGINX 的存活探測為: 被動探測.
當應用服務層 其中一個節點宕機的時候, nginx 能夠探測到, 會自動進行故障轉移, 不會將流量分發到發生故障的節點, 而是分發到其他的正常應用伺服器節點, 整個過程由 NGINX 自動完成, 對呼叫方透明.
資料庫層建議採用「主從同步, 讀寫分離」架構. 資料庫的高可用, 又可細分為: 「讀庫高可用」 和「寫庫高可用」 兩類.
ℹ️ 備註:
由於製造業採用了多種資料庫, 包括但不限於:
- Oracle
- SQL Server
- MySQL
不同資料庫的高可用解決方案並不完全相同, 所以本文不對資料庫的具體高可用技術做細節描述. 只進行理論論述.(以 MySQL 為例)
常見的資料庫高可用方案有:
- MySQL: 主從同步;
- Oracle: RAC
- SQL Server: Alwayon
讀庫高可用, 是通過讀庫的冗餘來實現的.
如果要對讀庫實現高可用, 一般來說至少有 2 個從庫, 資料庫連線池會建立與讀庫的多個連線, 每次請求會路由到這些讀庫.
當讀庫 - 從1發生宕機的時候, 應用服務層的資料庫連線池能夠探測到, 會自動的進行故障轉移, 將流量自動遷移到其他的讀庫, 如讀庫 - 從2, 整個過程由資料庫連線池自動完成, 對呼叫方是透明的.
ℹ️ 備註:
需要應用系統或中介軟體的資料庫連線層實現資料庫連線池功能.
寫庫的高可用, 是通過寫庫的冗餘來實現的.
以 MySQL 為例, 可以設定兩個 MySQL 雙主同步, 一臺對線上提供服務, 另一臺冗餘以保證高可用.
✔️ 選型結果:
ℹ️ 定義及概述:
在分散式系統中,負載均衡(load balance)是一種有效的將網路請求分配到多個伺服器的過程。通過將負載進行負載均衡,可以有效地改進系統響應時間,提高系統的可用性。隨著系統變的愈發複雜,使用者增多和網路流量增大,負載均衡已經成為系統設計中的必要一環。
負載均衡器可以是硬體也可以是軟體,它會將網路請求分發到伺服器叢集上。
常見的硬體負載均衡器包括:
常見的軟體負載均衡器包括:
結合製造行業最佳實踐, 以及製造業的實際情況考慮, 製造業在全國乃至全球擁有多座工廠, 每個工廠擁有獨立的機房. 採用硬體負載均衡成本過高. 確定採用軟體負載均衡器作為負載均衡技術實現. 下面對軟體負載均衡器逐一進行論述:
NGINX:
Nginx("engine x")是一款是由俄羅斯的程式設計師 Igor Sysoev 所開發高效能的 Web 和 反向代理 伺服器.
優點:
缺點:
ip_hash
實現源地址對談保持, 且可以通過第三方模組實現cookie對談保持.LVS:
LVS:使用 Linux 核心叢集實現一個高效能、高可用的負載均衡伺服器,它具有很好的可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。
優點:
缺點:
HAProxy:
HAProxy 是一個使用 C 語言編寫的自由及開放原始碼軟體,其提供高可用性、負載均衡,以及基於 TCP 和 HTTP 的應用程式代理。
優點:
缺點:
選型結論:
LVS 試用場景單一, 且存在硬傷(即: 後面有Windows Server的機器的話, 實施比較複雜). 直接排除.
HAPorxy 針對 HTTP 的支援沒有 NGINX 豐富, 且重啟中斷相對 NGINX 時間更長.
另外, nginx 除了當前可以用作負載均衡器之外, 還可以用作 web server, http 快取等場景, 且容易上手.
最終確定選擇 NGINX 作為某製造業公司負載均衡器.
NGINX 高可用技術方案只有一種, 即: NGINX + Keepalived 實現高可用.
keepalived
開源專案包括三個組成部分:
keepalived
Linux伺服器的守護程式。
虛擬路由器冗餘協定(VRRP)的實現,用於管理虛擬路由器(虛擬 IP 地址或 VIP)。
VRRP 確保始終存在一個主節點。備用節點偵聽來自主節點的 VRRP 通告包。如果在超過設定的廣播間隔的三倍的時間內未收到廣播包,則備用節點將作為主節點接管,並將設定的 VIP 分配給自己。
一種執行狀況檢查工具,用於確定服務(例如,Web 伺服器,PHP 後端或資料庫伺服器)是否已啟動並且可以執行。
如果節點上的服務未通過設定的執行狀況檢查次數,keepalived
則將虛擬 IP 地址從主(主動)節點重新分配給備用(被動)節點。
✔️選型結果:
負載均衡策略: RR(輪詢, 預設策略)
對談保持策略: (非必須)
ip_hash
NGINX負載均衡策略:
least_conn
.ip_hash
hash
- 指定伺服器組的負載均衡方法,其中客戶機-伺服器對映基於hash 值。key可以包含文字、變數及其組合。選型過程:
負載均衡策略,根據實際情況按需選擇,無特殊要求的情況下選擇 rr 即可。
對談保持策略, 需要根據特定的場景進行選擇:
ip_hash
cookie
對談保持: sticky
cookie
對談保持均無法滿足需求, 則可能需要通過 hash
來客製化對談保持策略.略.
由於應用系統的多樣性, 本文不對應用服務層 -> 資料庫層高可用選型做約束. 僅提供頂層架構要求:
參考檔案 |
---|
Availability - Wikipedia |
High Availability - Wikipedia |
system-design-primer - GitHub |
High Availability Support for NGINX |
Usage of web servers broken down by ranking |
三人行, 必有我師; 知識共用, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.