一、什麼是高可用?
高可用(High Availability)是分布式系統架構設計中必須考慮的因素之一,通常是指:通過設計從而減少系統不能提供服務的時間。
二、怎麼來衡量高可用?
舉個例子,比如說一個系統它一直能夠為你提供服務,那它的系統可用性就是100%,當系統運行到100個時間單位時,可能會有1-2個時間單位無法為你提供服務,那它的系統可用性就是99%和98%,在一年的時間內保證99%可用性的系統最多可以有3.65天的停機時間(1%)。這些值根據幾個因素計算的,包括計劃和非計劃維護周期,以及從可能的系統故障中恢復的時間。
目前大部分企業的高可用目標是4個9,也就是99.99%,有幾個 9,就代表了你的可用性。
- 2個9:基本可用,網站年度不可用時間小於 88 小時;
- 3個9:較高可用,網站年度不可用時間小於 9 小時;
- 4個9:具有自動恢復能力的高可用,網站年度不可用時間小於 53 分鐘;
- 5個9:極高可用,也就是很理想的狀態,網站年度不可用時間小於 5 分鐘;
可用性的9怎麼計算出來的呢?
- 網站不可用時間 = 故障修復時間點 – 故障發現時間點
- 網站年度可用性指標 =(1 – 網站不可用時間/年度總時間)* 100%
可用性的考核:網站可用性,跟技術、運營、等各方面的績效考核相關,因此在前期的架構設計中,關於系統高可用性的問題也會話很大一部分時間,互聯網企業不同公司有着不同的策略,往往因為種種因素會直接影響到系統的高可用性,業務增長較快的網站同時也將面臨著用戶的增長率,同時也慢慢會降低高可用性的標準,因此也就會對網站做一些相關性的策略或後端設備的支持等;
一般都是採用故障來分的,也是對網站故障進行分類加權計算故障責任的方法。一般會給每個分類的故障設置一個權重(例如事故級故障權重為100,A類為20等),計算公式為:故障分=故障時間(分鐘)* 故障權重。
三、高可用網站架構設計目的是什麼?
當服務器的集群設備頻繁讀寫時,會導致硬件出現故障的現象。
其高可用架構設計的目的:保證服務器硬件故障時服務依然可用、數據依然保存並能夠被訪問。
四、實現高可用的主要手段有哪些?
- 數據層面:冗餘備份
一旦某個服務器宕機,就將服務切換到其他可用的服務器上;
冗餘備份分為:冷備份和熱備份
冷備份是定期複製,不能保證數據可用性。
熱備份又分為異步熱備和同步熱備,異步熱備是指:多份數據副本的寫入操作異步完成,同步熱備是指:多份數據副本的寫入操作同時完成。

- 服務層面:失效轉移
如某塊磁盤損壞,將從備份的磁盤讀取數據。(首先是已經提前做好了數據同步操作);
若數據服務器集群中任何一台服務器宕機時,那麼應用程序針對這台服務器的所有讀寫操作都要重新路由到其他服務器,保證數據訪問不會失敗。

五、高可用的應用
應用層處理網站應用的業務邏輯,最顯著的特點是:應用的無狀態性。
無狀態性的應用是:指應用服務器不保存業務的上下文信息,僅根據每次請求提交的數據進行相應的業務邏輯處理,且多個服務實例(服務器)之間完全對等,請求提交到任意服務器,處理結果都是完全一樣的。

1)通過負載均衡進行無狀態服務的失效轉移
不保存狀態的應用是給高可用架構帶來了巨大便利,服務器不保存請求的狀態,所有的服務器完全對等;
當任意一台或多台服務器出現宕機時,請求提交給集群中的其他任意一台可用服務器進行處理,對客戶端用戶來講,請求總是成功的,整個系統依然可用。
對於應用服務器集群,實現這種服務器可用狀態實時檢測、自動轉移失敗任務的機制就是負載均衡。主要是在業務量和數據量使用頻率較高時,單台服務器不足以承擔所有的負載壓力,那麼可以通過負載均衡這種手段,將流量和數據平均到集群中其他服務器上,提高整體的負載處理能力。
不管在今後的工作中,是使用開源免費的負載均衡軟件還是硬件設備,都需具備失效轉移功能,網站應用中,集群中的服務器是無狀態對等時,負載均衡即可起到事實上高可用的作用。

當 Web 服務器集群中的服務器都可用時,負載均衡服務器會把客戶端發送到的訪問請求分發到任意一台服務器上來進行處理,這時當服務器2出現宕機時,負載均衡服務器通過心跳檢測機制發現該服務器失去響應,就會把它從服務器列表中刪除,而將請求發送到 Web 服務器集群中的其他服務器上,這些服務器完全一樣,請求在任何一台服務器中處理都不會影響到最終結果。
在實際環境中,負載均衡在應用層起到了系統高可用的作用,即便當某個應用訪問量較少時,只用一台服務器足以支撐並提供服務,一旦需要保證該服務高可用時,必須至少部署兩台服務器,從而使用負載均衡技術搭建一個小型的 Web 服務器集群。
2)應用服務器集群的Session管理
Web 應用中將多次請求修改使用的上下文對象稱為會話(Session),單機情況下,Session 可部署在服務器上得 Web 容器(如 IIS、Tomcat 等)管理。
在使用了負載均衡的集群環境中,負載均衡服務器可能會將請求分發到 Web 服務器集群中的任何一台應用服務器上,所以保證每次請求能夠獲得正確的 Session 比單機時要複雜得多。
在集群環境中,Session 管理的幾種常見手段:
- Session 複製
Session 複製:簡單易行,是早期企業應用系統使用較多的一種服務器集群 Session 管理機制。應用服務器開啟 Web 容器的 Session 複製功能,在集群中的其他服務器之間將會同步 Session 對象,與其使得每台服務器上都將會保存所有用戶的 Session 信息。
當集群中的任何一台服務器出現宕機時,都不會導致 Session 數據的丟失,而服務器使用 Session 時,也只需要在本機獲取即可。
Session 複製這種方案只適合集群規模較小的環境,當規模較大時,大量的 Session 複製操作會佔用服務器和網絡的大量資源,系統也將面臨很大的壓力。
所有用戶的 Session 信息在每台服務器上都有備份,當大量用戶訪問時,甚至會出現服務器內存不夠 Session 使用的情況,大型網站的核心應用集群都是數千台服務器以上,同時在線用戶可達上千萬,並不適合用 Session 複製這種方案。

- Session 綁定
Session 綁定是利用負載均衡的源地址 Hash 算法實現的,負載均衡服務器總是將來源於同一 IP 的請求分發到同一台服務器上,在整個會話期間,用戶所有的請求都在同一台服務器上處理,Session 綁定在某台特定服務器上,保證 Session 總能在這台服務器上獲取,因此這種方法被稱作會話粘滯。
但 Session 綁定這種方案不符合對於系統高可用的需求,一旦某台服務器出現宕機,那麼該機器上的 Session 也將不存在了,用戶請求切換到其他服務器上後,因此沒有 Session 也將無法完成業務處理,大部分負載均衡服務器都提供源地址負載均衡算法,但很少有網站利用這個算法進行 Session 管理。

- Cookie 記錄 Session
早期企業應用系統使用 C/S(客戶端/服務器)架構,一種管理 Session 的方式是將 Session 記錄在客戶端,客戶端請求服務器的時候,將 Session 放在請求中發送給服務器,服務器處理完請求後再將修改過的 Session 響應給客戶端。因為網站沒有客戶端,因此利用瀏覽器支持的 Cookie 記錄 Session。
利用瀏覽器支持的 Cookie 記錄 Session 缺點:
- 受 Cookie 大小限制,能記錄的信息有限
- 每次請求響應都需要傳輸 Cookie ,影響性能
- 如用戶關閉 Cookie ,訪問將會不正常
Cookie 簡單易用,可用性高,支持應用服務器的線性伸縮,大部分應用需要記錄的 Session 信息比較小。因此許多網站都將會使用 Cookie 來記錄 Session。

- Session 服務器
利用獨立部署的 Session 服務器或集群統一管理 Session ,應用服務器每次讀寫 Session 時,都將會訪問 Session 服務器。其實是將應用服務器的狀態進行分離為:無狀態的應用服務器和有狀態的 Session 服務器,針對這兩種服務器的不同特性分別設計其架構。
對於有狀態的 Session 服務器是利用分布式緩存、數據庫等,在這些產品的基礎上進行封裝,使其符合 Session 的存儲和訪問要求。如果業務場景對 Session 管理有比較高的要求可利用 Session 服務集成單點登錄、用戶服務等功能,則需專門開發 Session 服務管理平台。

六、高可用的服務
高可用的服務是用的服務模塊為:業務產品提供基礎公共服務,在大型網站中這些服務通常都獨立分布式部署,被具體應用遠程調用。可復用的服務和應用一樣,是無狀態的服務,可使用類似負載均衡的失效轉移策略實現高可用的服務。
在具體實踐中,高可用的幾點服務策略:
- 分級管理:運維上將服務器進行分級管理,核心應用和服務優先使用更好的硬件,在運維響應速度上也格外迅速,同時在服務部署上也進行必要的隔離,避免故障的連鎖反應,低優先級的服務通過啟動不同的線程或者部署在不同的虛擬機上進行隔離,而高優先級的服務則需要部署在不同的物理機上,核心服務和數據甚至需要部署在不同地域的數據中心。
- 超時設置:在應用程序中設置服務調用的超時時間,一旦超時後,通信框架拋出異常,應用程序則根據服務調度策略選擇重試或將請求轉移到提供相同服務的其他服務器上;
- 異步調用:通過消息隊列等異步方式完成,避免一個服務失敗導致整個應用請求失敗的情況;
- 服務降級:網站訪問高峰期間,服務到大量並發調用時,性能會下降,可能會導致服務宕機,為保證核心應用及功能能夠正常運行,需要對服務降級;
降級有兩種手段:
一:拒絕服務,拒絕較低優先級的應用的調用,減少服務調用並發數,確保核心應用的正常運行;
二:關閉功能,關閉部分不重要的服務,或者服務內部關閉部分不重要的功能,以節約系統開銷,為核心應用服務讓出資源;
- 冪等性設計:應用調用服務失敗後,會將調用請求重新發送到其他服務器,服務重複調用時無法避免的,應用層其實不關心你服務是否真的失敗,只要沒有收到調用成功的響應,就認為調用失敗,並重試服務調用。因此必須在服務層保證服務重複調用和調用一次產生的結果相同,即服務具有冪等性。
七、常見的互聯網分層架構

整個系統的高可用,又是通過每一層的冗餘+自動故障轉移來綜合實現,而常見互聯網分布式架構如上,分為:
- 客戶端層:典型調用方是瀏覽器 browser 或者手機應用 APP
- 反向代理層:系統入口,反向代理
- 站點應用層:實現核心應用邏輯,返回 html 或者 json
- 服務層:如果實現了服務化,就有這一層
- 數據-緩存層:緩存加速訪問存儲
- 數據-數據庫層:數據庫固化數據存儲
八、分層高可用架構
客戶端層 –> 反向代理層的高可用

客戶端層到反向代理層的高可用,通過反向代理層的冗餘來實現。以 Nginx 服務為例:需準備兩台 Nginx,一台對線上提供服務,另一台做冗餘保證高可用,常見的實踐是keepalived存活探測,相同虛擬 IP(virtual IP)來提供服務。

自動故障轉移:當一台Nginx宕機時,Keepalived能夠檢測到,會自動的將故障進行轉移,使用的是相同的虛擬IP,切換過程對調用方是透明的。
反向代理層 –> 站點層的高可用

反向代理層到站點層的高可用,通過站點層的冗餘來實現,反向代理層是Nginx,Nginx.conf 里能夠配置多個 Web 後端,並且 Nginx 能夠檢測多個後端的存活性。

故障自動轉移:當 Web-server 宕機時,Nginx 能夠檢測到,會自動進行故障轉移,將流量自動轉移到其他的 Web-server,整個過程由 Nginx 自動完成,對調用方是透明的。
站點層 –> 服務層的高可用

站點層到服務層的高可用,是通過服務層的冗餘來實現的。“服務連接池”會建立與下游服務多個連接,每次請求會“隨機”選取連接來訪問下游服務。

故障自動轉移:當 service 宕機時,service-connection-pool 能夠檢測到,會自動的進行故障轉移,將流量自動轉移到其他的 service,整個過程由連接池自動完成,對調用方是透明的(RPC-client 中的服務連接池是很重要的基礎組件)。
服務層 –> 緩存層的高可用

服務層到緩存層的高可用,是通過緩存數據的冗餘來實現,緩存層的數據冗餘可通過利用客戶端的封裝,service 對 cache 進行雙讀或者雙寫方式。

緩存層也可以通過支持主從同步的緩存集群來解決緩存層的高可用問題,redis 天然支持主從同步,redis也有 sentinel 機制,來做 redis 的存活性檢測。

自動故障轉移:當 redis 主掛了的時候,sentinel 能夠檢測到,會通知調用方訪問新的redis,整個過程由 sentinel 和 redis 集群配合完成,對調用方是透明的。
服務層 –> 數據庫層的高可用,大部分互聯網數據庫層都將採用了主從複製,讀寫分離架構,所以數據庫層的高可用又分為讀庫高可用與寫庫高可用兩類。
服務層 –> 數據庫層讀的高可用

服務層到數據庫讀的高可用,是通過讀庫的冗餘來實現,冗餘了讀庫,一般來說就至少有2個從庫,數據庫連接池會建立與讀庫多個連接,每次請求會路由到這些讀庫裡面去。

故障自動轉移:當一台讀庫宕機時,db-connection-pool 能夠檢測到,會自動的進行故障轉移,將流量自動遷移到其他的讀庫,整個過程由連接池自動完成,對調用方是透明的,數據庫連接池是很重要的基礎組件。
服務層 –> 數據庫層寫的高可用

服務層到數據庫寫的高可用,是通過寫庫的冗餘來實現,可以設置兩台MySQL雙主同步,一台對線上提供服務,另一台做冗餘以保證高可用,常見的實踐是keepalived存活探測,相同虛擬IP(virtual IP)提供服務。

故障自動轉移:當寫庫宕機時,keepalived能夠檢測到,會自動的進行故障轉移,將流量自動遷移到shadow-db-master,使用的是相同的虛擬IP(virtual IP),這個切換過程對調用方是透明的。
九、配置高可用的準備工作

1、 準備兩台 Nginx 服務器(IP 地址:192.168.1.10 和 192.168.1.11),並在兩台 Nginx 服務器上安裝Keepalived,以及配置虛擬 IP 地址;
2、 192.168.1.10 服務器,因為我們前期就已經安裝好了 Nginx,無須在重新安裝了,只需在 192.168.1.11 設備上安裝 Nginx 服務即可;
3、 分別在兩台Nginx服務器上安裝Keepalived服務,可通過 rpm 包或 yum 一鍵安裝,這兩種安裝方式都是可以的,根據個人所需安裝即可;
# rpm -ivh /mnt/Packages/keepalived-1.2.7-3.el6.x86_64.rpm
# yum -y install keepalived4、 在兩台Nginx服務器上分別啟動Nginx服務和keepalived服務;
# cd /usr/local/nginx/sbin
# ./nginx
# service keepalived start
正在啟動 keepalived: [確定]
5、 在客戶端瀏覽器中分別輸入192.168.1.10和192.168.1.11進行驗證是否能夠正常訪問Nginx服務;

十、配置高可用的主備模式實操案例
主備方案:這種方案也是目前企業中最常用的一種高可用的方案,簡單來說,就是指一台服務器在提供服務時,另一台服務器為其他服務且是備用狀態,當一台服務器出現宕機時,將自動跳轉至備用服務器上,因此客戶端所發出的請求將不會出現有失敗現象。
在上述的準備工作介紹到了本次配置高可用將採用Keepalived來實現,那麼什麼是Keepalived?
Keepalived是一款服務器狀態檢測和故障切換的工具,起初是專為LVS負載均衡軟件設計的,用來管理並監控LVS集群系統中各個服務節點的狀態,後來又加入了可以實現高可用的VRRP (Virtual Router Redundancy Protocol ,虛擬路由器冗餘協議)功能。
因此,Keepalived除了能夠管理LVS軟件外,還可以作為其他服務(例如:Nginx、Haproxy、MySQL等)的高可用解決方案軟件在其配置文件中,可以配置主備服務器和該服務器的狀態檢測請求。也就是說keepalived可以根據配置的請求,在提供服務期間不斷向指定服務器發送請求,如果該請求返回的狀態碼是200,則表示該服務器狀態是正常的,如果不正常,那麼Keepalived就會將該服務器給下線掉,然後將備用服務器設置為上線狀態,而當主服務器節點恢復時,備服務器節點會釋放主節點故障時自身接管的 IP 資源及服務,恢復到原來的備用角色。
1、 主服務器上配置keepalived.conf配置文件
# vim /etc/keepalived/keepalived.conf
1 global_defs {
2 notification_email {
3 acassen@firewall.loc
4 failover@firewall.loc
5 sysadmin@firewall.loc
6 }
7 notification_email_from Alexandre.Cassen@firewall.loc
8 smtp_server 192.168.1.10 # 主服務器 IP 地址
9 smtp_connect_timeout 30
10 router_id LVS_DEVEL
11 }
12
13 vrrp_script chk_http_port {
14
15 script "/usr/local/src/nginx_check.sh" # nginx_check.sh 腳本路徑
16
17 interval 2 # 檢測腳本執行的間隔
18
19 weight 2
20
21 }
22
23 vrrp_instance VI_1 {
24 state MASTER # 指定當前節點為 master 節點
25 interface eth0 # 這裡的 eth0 是網卡的名稱,通過 ifconfig 或者 ip addr 可以查看
26 virtual_router_id 51 # 這裡指定的是虛擬路由 id,master 節點和 backup 節點需要指定一樣的
27 priority 90 # 指定了當前節點的優先級,數值越大優先級越高,master 節點要高於 backup 節點
28 advert_int 1 # 指定發送VRRP通告的間隔,單位是秒
29 authentication {
30 auth_type PASS # 鑒權,默認通過
31 auth_pass 1111 # 鑒權訪問密碼
32 }
33 virtual_ipadress {
34 192.168.1.100 # 虛擬 IP 地址
35 }
36 }2、 從服務器上配置keepalived.conf配置文件
# vim /etc/keepalived/keepalived.conf
1 global_defs {
2 notification_email {
3 acassen@firewall.loc
4 failover@firewall.loc
5 sysadmin@firewall.loc
6 }
7 notification_email_from Alexandre.Cassen@firewall.loc
8 smtp_server 192.168.1.10 # 主服務器 IP 地址
9 smtp_connect_timeout 30
10 router_id LVS_DEVEL
11 }
12
13 vrrp_script chk_http_port {
14
15 script "/usr/local/src/nginx_check.sh" # nginx_check.sh 腳本路徑
16
17 interval 2 # 檢測腳本執行的間隔
18
19 weight 2
20
21 }
22
23 vrrp_instance VI_1 {
24 state BACKUP # 指定當前節點為 BACKUP 節點
25 interface eth1 # 這裡的 eth0 是網卡的名稱,通過 ifconfig 或者 ip addr 可以查看
26 virtual_router_id 51 # 這裡指定的是虛擬路由 id,master 節點和 backup 節點需要指定一樣的
27 priority 80 # 指定了當前節點的優先級,數值越大優先級越高,master 節點要高於 backup 節點
28 advert_int 1 # 指定發送VRRP通告的間隔,單位是秒
29 authentication {
30 auth_type PASS # 鑒權,默認通過
31 auth_pass 1111 # 鑒權訪問密碼
32 }
33 virtual_ipadress {
34 192.168.1.100 # 虛擬 IP 地址
35 }
36 }3、 將nginx_check.sh腳本分別放置在兩台Nginx服務器的/usr/local/src/目錄下,用於通過Keepalived來檢測Nginx主服務器是否還活着,如果是已經宕機了,將自動切換至從服務器上面去。
# vi /usr/local/src/nginx_check.sh
1 #!/bin/bash
2 A=`ps -C nginx ¨Cno-header |wc -l`
3 if [ $A -eq 0 ];then
4 /usr/local/nginx/sbin/nginx
5 sleep 2
6 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
7 killall keepalived
8 fi
9 fi4、 在兩台Nginx服務器上分別配置虛擬 IP 地址,對客戶端的響應是真實服務器直接返回給客戶端的,而真實服務器需要將響應報文中的源 IP 地址修改為虛擬 IP 地址,這裡配置的虛擬 IP 地址就是起這個作用的。
主服務器
# ifconfig eth0:1 192.168.1.100 netmask 255.255.255.0
從服務器
# ifconfig eth1:1 192.168.1.100 netmask 255.255.255.05、 在兩台Nginx服務器上分別重啟Nginx服務和Keepalived服務;
# ./nginx -s stop
# ./nginx
# service keepalived restart6、 在客戶端瀏覽器中輸入虛擬 IP 地址192.168.1.100測試訪問結果;

十一、模擬主服務器故障驗證高可用的效果
將主服務器的Nginx服務和Keepalived服務,都進行停止。
# ./nginx -s stop
# service keepalived stop
停止 keepalived: [確定]通過客戶端瀏覽器再次輸入虛擬 IP 地址 192.168.1.100進行驗證,可以發現還是能夠正常訪問Nginx服務,也就說明了當主服務器宕機時,將自動切換到從服務器上,因此不受客戶端所訪問造成的影響。
總結
通過本篇文章介紹了什麼是高可用、如何來衡量高可用、高可用網站架構設計的目的、實現高可用的主要手段、高可用的應用及服務、常見的互聯網分層架構、分層高可用架構詳解、配置高可用的準備工作、主備模式的實操高可用案例以及模擬主服務故障從而來驗證整個高可用的效果。
整個互聯網分層系統架構的高可用,是通過每一層的冗餘+自動故障轉移來實現的,具體的:
- 【客戶端層】到【反向代理層】的高可用:是通過反向代理層的冗餘實現的,常見實踐是keepalived + virtual IP自動故障轉移;
- 【反向代理層】到【站點層】的高可用:是通過站點層的冗餘實現的,常見實踐是nginx與web-server之間的存活性探測與自動故障轉移;
- 【站點層】到【服務層】的高可用:是通過服務層的冗餘實現的,常見實踐是通過service-connection-pool來保證自動故障轉移;
- 【服務層】到【緩存層】的高可用:是通過緩存數據的冗餘實現的,常見實踐是緩存客戶端雙讀雙寫,或者利用緩存集群的主從數據同步與sentinel與自動故障轉移;更多業務場景,對緩存沒有高可用要求,可使用緩存服務化來對調用方屏蔽底層複雜性;
- 【服務層】到【數據庫“讀”】的高可用:是通過讀庫的冗餘實現的,常見實踐是通過db-connection-pool來保證自動故障轉移;
- 【服務層】到【數據庫“寫”】的高可用:是通過寫庫的冗餘實現的,常見實踐是keepalived + virtual IP自動故障轉移;
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/290293.html
微信掃一掃
支付寶掃一掃