您好,登錄后才能下訂單哦!
本篇內容介紹了“如何做系統高可用的健康檢查”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
隨著人們的生活水平的不斷提高,人們對身體健康越來越重視,很多人都做過體檢,一般公司都會有一年一度的體檢福利,健康體檢是家喻戶曉了。
隨著互聯網的快速發展,同類同質產品之間的競爭越來越大,產品之間一個重要的差異就是用戶體驗。影響用戶體驗的,除了產品設計因素外,技術層面也是一個重要的影響因素,主要體現在服務的可用性和響應速度。提升服務可用性和響應速度如此重要,為了實現這樣的目標,必須要有相應的手段,其中健康檢查就是保障服務可用性和快速響應一個非常重要的前提。
健康體檢是指通過醫學手段和方法對受檢者進行身體檢查,了解受檢者健康狀況、早期發現疾病線索和健康隱患的診療行為。而系統的健康檢查是利用技術手段檢測網絡、主機、應用、服務等一系列對象是否健康或可用的過程。
互聯網產品對用戶體驗提出了很高的要求,但常常由于技術側原因,發生服務響應慢或者服務不可用等一系列影響用戶體驗的問題,導致業務中斷,影響收入,公司品牌和口碑也會受到巨大的負面影響。
影響服務不可用和響應慢的因素很多,可能是服務硬件損壞、光纖被挖斷,可能是請求量過大導致數據庫CPU負載、磁盤IO過高,又可能是某同學埋了雷,新上線的功能第一次運行就發生了OOM……
要保證系統高可用,我們應該怎么做呢?有人說,系統節點冗余消除單節點故障不就行了嗎。說的沒錯,消除單節點是系統高可用的常用手段。消除單節點有一個很重要的前提是發現問題節點,把問題節點踢除或者把流量切換到其他正常節點。
如何“發現問題節點”,就是系統健康檢查需要做的事情。
談論如何做健康檢查前,首先要弄明白的是要檢查的對象究竟是誰。對象可以網絡連接,可以是一個小小的功能組件,可以是一個進程,可以是服務集群,也可以是機房單元。所以,要做到“高可用”,首先要弄清楚要做哪層面的高可用,哪些對象可能存在單點問題,要把“對象”搞清楚。
那么,健康檢查如何做呢?通常有兩種方式:主動和被動。
由檢查方作為主動方,定時主動發起健康檢查請求,請求的報文內容或者格式通常是獨立設計的,被健康的對象作簡單自檢后返回響應。舉個例子:
check interval=3000 rise=2 fall=5 timeout=1000 type=http; check_http_send "HEAD /check.do HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx;
配置間隔2000豪秒定時向后臺web服務器http://(ip:port)/check.do接口發送檢查請求,如果連續失敗次數達到fall=5次,服務器被認為宕機,如果連續成功次數達到rise=2次,服務器被認為是up健康狀態。當然了,響應狀態碼必須是2xx或者3xx才被認為是健康狀態。
被動健康檢查不設計獨立的健康檢查請求,而是以正常連接情況或者業務請求的響應作為指標來衡量檢查對象的健康狀態。例如nginx官方開源版本的被動健康檢查配置:
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
Nginx是基于連接探測,如果在30s內嘗試連接3次失敗,則認為后端web服務不可用。
上面談到,要實現高可用就要消除單點故障,最簡單直接的方案加備服務節點,通過定時心跳健康檢查發現主服務節點宕機后,備服務節點把主的工作接管過來,客戶端把請求流量切換到備服務節點。
主服務節點與備服務節點之間通過專用的心跳線進行健康檢查,由于網絡分區等原因它們可能無法收到對方心跳,這時備節點會認為主節點已宕機,主節點也認為備節點已宕機,但其實主從兩節點狀態都是正常的,客戶端能正常訪問到主從兩節點,出現“雙寫”,這種現象在業界稱為“腦裂(split-brain)”。
出現腦裂會導致數據混亂的災難事件發生,影響業務的正確性,這時引入第三方機構進行仲裁可以有效避免腦裂的發生。出現腦裂會導致數據混亂的災難事件發生,影響業務的正確性,這時引入第三方機構進行仲裁可以有效避免腦裂的發生。
既然主從雙方無法確認對方的存活,出現爭議時可以由第三方仲裁節點做出決定,到底誰是主由它說了算,第三方仲裁節點一般是由Zookeeper這種高可用方案來實現。
Keepalived是一款保證集群高可用的服務軟件,其功能類似于heartbeat,用于防止單點故障。但是它一般不會單獨出現,而是與其它負載均衡技術(如LVS、HAProxy、Nginx)一起工作來達到集群的高可用。
它的健康檢查也包含兩個方面,一個是Keepalived組件之間的健康檢查(通過VRRP心跳報文),如下圖所示
另一個是Keepalived組件與本地負載均衡組件的健康檢查,配置如下:
vrrp_script check_nginx_running { script "/usr/local/bin/check_running"(定義腳本) interval 10(腳本執行的間隔) weight -10(腳本執行的優先級) }
其中,應用的健康檢查方式通過自定義腳本實現。
Keepalived組件之間通過VRRP協議進行健康檢查,如果主服務器宕機,備服務器通過VRRP協議選舉成為新的主服務器,把虛擬IP從舊的主服務器上爭搶過來,實現高可用。
VRRP報文是封裝在IP報文上的,支持各種上層協議,網絡設備通常也是使用VRRP協議實現主備高可用切換,如交換機、路由器、防火墻等。
當網絡設備發生故障時,VRRP機制能夠選舉出新的網絡設備承擔數據流量,從而保障網絡的可靠通信。
移動設備連接互聯網通過NAT方式,移動App的PUSH推送需要與服務器保持長連接,但大部分移動網絡運營商都在連接一段時間沒有數據交互時,會淘汰 NAT列表中的對應連接,造成連接中斷。為了保持網絡連接的“健康”可用,我們可以在連接建立后,App與服務器互相定期發送Ping Pong心跳信息來保持連接的持續有效。
以上是應用層的連接健康檢查方案,操作系統也支持底層網絡的連接健康檢查即Keepalive。TCP Keepalive可以在連接無活動一段時間后,發送一個空的探測報文,使TCP連接不會被客戶端或者防火墻等中間網絡設備關閉。Linux可以通過以下三個參數對Keepalive的間隔、頻率和閾值和進行配置:
net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9
主機之間的可達性可以通過Ping命令進行識別,Ping命令使用的是ICMP協議,它能識別從客戶端到目標主機整個路徑的網絡連通性。Ping通常用于手工測試某臺主機是否啟動和網絡是否聯通。
ICMP是網絡層協議,與具體進程是沒關系的,無法通過Ping識別進程是否存在。但進程有端口,有進程信息,可以通過telnet端口或ps命令檢測進程是否存在。進程可能會由于內存不足被kill或者其他原因異常關閉,可以通過cron定時腳本檢測識別后自動拉起,這種方案對老破舊項目中只能單實例部署的應用的可用性提升非常有效。
NameServer是RocketMQ的路由中心,NameServer中維護著Producer集群、Broker集群、 Consumer集群的服務狀態和路由信息。當有新的Consumer加入集群時,除了上報自身信息外,還獲取各個Broker的地址、Topic、隊列等信息,這樣就能知道它消費的Topic消息存儲到哪個Broker和隊列上。
NameServer可以部署多個,NameServer之間相互獨立不互通。Producer、Broker、Consumer服務啟動時需要指定多個NameServer,服務的信息會同時注冊到多個指定的 NameServer上,達到高可用。
每個Broker節點與所有NameServer會保持TCP長連接,每隔30s給NameServer發送心跳報文,告訴NameServer自己還活著。而每個NameServer每隔10s檢查一下各個Broker的最近一次心跳時間,如果發現某個Broker超過120s都沒發送心跳報文,就認為這個Broker已經宕機了,會關閉對應的網絡連接channel,并將其從路由信息里移除。
一個服務實例或者進程會通過定期的心跳包向其他服務來報告它的存活,但有這個心跳包還是不夠的,不足以反映它的健康狀況。比如磁盤空間不足了,服務已經無法再寫數據了,但它還能響應心跳包;服務依賴Redis,但Redis服務出了問題連接不上,但它還能響應心跳包;服務的某些功能依賴分布式存儲服務,但分布式存儲服務不可用了,但它依然能響應心跳包。我們可以看到,要確定一個服務實例是否存活并且“健康”,還是有很多方面需要考慮的。Spring Boot Actuator能比較好的解決這個問題,它能反映整個服務的健康狀況,包括它所依賴的子系統的健康狀況。
Spring Boot Actuator是Spring Boot的一個子項目,Actuator提供Endpoint(端點)給外部應用程序進行訪問和交互。Actuator包括許多功能,比如健康檢查、審計、指標收集等等,可幫助我們監控和管理Spring Boot應用程序。Health就是其中一個Endpoint,它提供了關于Spring Boot應用的基本健康情況信息,允許其他云服務或者k8s等定時檢測到應用的健康狀況,對異常情況及時作出響應。
假如某微服務應用使用到了MySQL、Amazon S3、Elastic Search、DynamocDB這些資源系統,它的健康檢查結果就應該包含所有這些子系統的健康狀況:
Actuator的健康檢查由HealthIndicator接口實現,HealthIndicator接口只有一個health()方法,返回值是Health健康對象。
@FuncationalInterface public class HealthIndicator { /** * Return an indication of health. * @result the health for */ public Health health(); }
Health對象有狀態status和details兩個字段,status默認有UNKNOWN、UP、DOWN和OUT_OF_SERVICE四個值,用戶可以自定義和擴展,details是一個KV結構,用戶可以隨意自定義要返回的數據值。
@JsonInclude(Include.NON_EMPTY) public final class Health extends HealthComponent { private final Status status; private final Map<String, Object> details; ... }
Actuator內置了很多常用的HealthIndicator:
用戶可以根據實際情況自定義,比如:
@Override public Health health() { int errorCode = check(); // perform some specific health check if (errorCode != 0) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build(); }
默認情況下health的狀態是啟用且對外開放的,通過http://locahost:8080/actuator/health就可以查詢到應用的健康狀態:{“status”: “UP”},這是一個匯總的狀態,詳細的健康信息可以通過配置項management.endpoint.health.show-details=always打開,一個完整的包含details的健康檢查信息如下:
匯總的健康狀態由 HealthAggregator 匯總而成的,匯總的算法是:所有子系統的健康狀態按DOWN、OUT_OF_SERVICE、UP、UNKNOWN這個順序進行排序取最前面一個狀態值。
比如ehCache是UP,MySQL是UNKNOWN,diskSpace是OUT_OF_SERVICE;那么排序下來就是:OUT_OF_SERVICE、UP、UNKNOWN,取第一個就是OUT_OF_SERVICE,即服務不可用。
“如何做系統高可用的健康檢查”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。