問題初現
「滴~~~」,釘釘突然響起了很多客服轉發來的用戶投訴信息,說是網絡連接不上了,經過排查發現是其中一臺機器(RS2)掛了
但是 LVS 依然持續地把流量打到這臺機器上,持續造成線上問題,小章首先把這臺機器從 LVS 上摘除,先保證線上正常,然后為了避免之后出現類似問題,急忙找了 CEO 老梁來商討方案。
應用層健康檢查:HTTP 檢測
老梁一眼看出了問題所在:「我們需要開發一個健康檢查服務,部署在 LVS 上,這個服務可以定時檢查其后的 RS 是否可用,如果不可用則將 RS 摘除,這樣就可以保障線上服務正常了」
「妙啊,通過軟件及時探測,摘除不可用的機器,避免了人工發現不及時的問題,那么該怎么做這個健康檢查呢,需要滿足什么條件呢」聽說要開發這樣的軟件,小章頓時來了興致。
「小章啊,仔細想想看,我們的服務在發布過程中其實也是有健康檢查的,要保證一個工程可用,至少保證它是可訪問的以及它用到的中間件,DAO 是正常的,所以它的健康代碼如下
@Service(protocol={"rest"}) publicclassHealthCheckServiceImplimplementsHealthCheckService{ @Resource privateTestDAOTestDAO; @Resource privateRebateClientrebateClient; @Override publicStringgetHealthStatus(){ List
testDOS= TestDAO.getResult(123); Assert.isTrue(testDOS!=null,"rebateMemberDOSnull"); //此處省略redis檢測 //此處省略其它檢測 return"health"; } }
如以上代碼所示,我們在工程里寫了健康檢查 HealthCheckService 類,暴露了一個 rest 服務,這樣的話在部署的時候在服務部署腳本里首先訪問一下此服務的 getHealthStatus 方法,如果返回的值為「health」,則說明此服務的 dubbo 服務,DAO,redis 等正常,說明此服務是沒有問題的,如果返回的值不為 health,則說明此服務有問題,不能上線,這就是我們所說的健康檢查,通過訪問服務暴露的方法,來檢測此服務是否可用。
所以我們要開發的檢測服務也與此類似,只要定時訪問此服務暴露的接口,看下此接口返回的值與我們期待的值是否一致即可,一致說明此服務正常,否則,說明此服務異常,將其剔除,當然了一次連接不通就判斷為不可用可能有些問題,我們可以提供一個重試次數,比如 3 次,如果 3 次健康檢測都失敗,則認定此服務不可用!配置的偽代碼如下:
real_server192.168.1.22080{
HTTP_GET{
url{
path/healthCheck
status_code200
}
connect_timeout3
nb_get_retry3//置超時重試次數
}
}
「妙啊,此法甚好!只要訪問健康檢查服務就可以很方便地查看此服務是否正常了,但是有個問題:如果這個健康檢測方法寫的檢測邏輯很多,而 LVS 定時發檢測請求比較頻繁的話可能會有一定的性能問題,是否有更輕量級的檢測方法呢」小章說道
「考慮得很周到!一般健康檢測確實邏輯比較重,所以只在部署的的時候檢測一次就夠了,在生產上我們可以采用更輕量的檢測方式:TCP連接檢測」
TCP連接檢測
TCP 連接檢測原理很簡單,我們知道要建立一個 TCP 連接,首先必須由 TCP 客戶端發起 connect 請求,三次握手成功后才算建立起一個 TCP 鏈接,然后才能正常收發數據
所以我們只要調用 connect 方法看它是否成功即可,成功即說明連接建立成功,說明服務是可用的,如果失敗說明此服務有問題,直接摘除即可,當然了與 HTTP 檢測一樣,也要有超時機制,偽代碼如下
tcp連接檢測
TCP_CHECK{
connect_port80//指定端口
connect_timeout6//設置響應超時時間
nb_get_retry3//設置超時重試次數
delay_before_retry3//設置超時重試間隔時間
}
小章按著老梁的思路把這兩種健康檢測思路給實現了,并且給這個服務取了個霸氣的名字:keepalived,老梁很滿意,不過他又發現了新的問題。。。
單點故障---高可用解決之道
「小章,健康檢查做得很好,而且提供了兩種檢查方式,很全面,不過你這個架構還有個很致命的問題,不知你有沒發現,那就是目前只有一臺 LVS 在工作,如果這臺 LVS 掛了,那我們業務就跌零了, 你還需要讓 keepalived 支持 LVS 的高可用」
小章恍然大悟,「那該咋辦呢」
「高可用的通用解決方案很簡單,冗余+故障自動發現轉移,我們可以按照這個思路來設計 LVS 高可用,具體方案如下:
我們可以為 LVS 準備幾臺備機,如果發現 LVS 掛了,就讓備機頂上去,這樣不就實現了高可用了嗎」不愧是 CTO,一語中的
小章看了一眼架構圖,提出了三個問題
-
如果主機(以下簡稱 master)宕機,備機(以下簡稱 backup)頂上,那 IP 地址不是變了嗎,此時客戶端該怎么連接
-
幾臺機器首次啟動時,誰為 master,誰為 backup
-
master 宕機后,backup 是如何感知到的,多臺 backup 又是如何競選出主機的,這個和問題 2 有點類似
「這幾個問題提的很好,正是實現高可用的關鍵,可以看出小伙子還是有經過深入思考的」老梁高興地說,「這些問題不難化解,我們一一來看看」
問題一:backup 成為 master 后,IP 地址變了怎么辦?
答:IP 地址不能變,對外必須表現為一個 IP,我們通常稱為「虛擬(virtual) IP」,通常簡稱為 VIP
如果 master(即圖中的 L1)工作,則此 VIP 在 master 上可用,若 master 宕機,如果 backup(比如 L2)競選 master 成功,則 VIP 在 L2 上生效,同時新的 master 需要發送一個攜帶有本機的 MAC 地址和 VIP 地址信息的 ARP 報文,你會發現 VIP 從老的 master 轉移到競選 master 成功的 backup 上了,我們把這種現象稱為 IP 漂移,這里有兩個問題需要澄清
-
一個主機如何才能有兩個 IP
-
為什么 VIP 在某臺競選 master 成功的 backup 上生效后要發一個攜帶有本機的 MAC 地址和 VIP 地址信息的 ARP 報文
先看第一個問題,主機如何才能擁有兩個 IP ,畢竟一臺機器成為主機后,除了本身機器被分配的 IP(115.205.4.210),VIP 也漂移到它身上了,此時它擁有兩個 IP
我們知道計算機要上網,首先要把網線插入網卡,一個網卡其實就對應著一個 IP,所以一臺主機配兩個網卡就可以綁定兩個 IP,一般 LVS 都會配置雙網卡,一來每個網卡帶寬都是有限的,雙網卡相當于提升了一倍的帶寬,二來兩個網卡也起到了熱備的作用,如果一個網卡壞了,另外一個可以頂上。
但有人說了,我就只有一個網卡,也想配置多個 IP,是否可以?
答案是可以的,網卡一般分兩種,一種是物理網卡,一種是虛擬網卡
-
物理網卡
:可以插網線的網卡,如果有多個網卡,我們一般將其命名為 eth0,eth1。。。,如果一個網卡對應多個 IP,以 eth0 為例,一般將其命名為 eth0,eth0:0,eth0:1。。。eth0:x,比如一臺機器只有一個網卡,但其對應兩個 IP 192.168.1.2, 192.168.1.3,那么其綁定的網卡名稱分別為 eth0,eth0:0 -
虛擬網卡
:虛擬網卡通常被稱為 loopback,一般命名為 lo,是一個特殊的網絡接口,主要用于本機中各個應用之間的網絡交互(哪怕網線拔了,本機各個應用之間通過 lo 也是能通信的),需要注意的是虛擬網卡和物理網卡一樣,也可以綁定任意 IP 地址,如果在虛擬網卡配置了任何的 IP 地址,只要有物理網卡,就能到收到并處理目的 IP 為虛擬網卡上 IP 的數據包,lo 默認綁定了 127.0.0.1 這個本地 IP ,如果要綁定其他的 IP,對應的網卡命名一般為 lo:0,lo:1。。。
所以假設一臺機器只有一個網卡,一般內網給它默認分配的 IP 綁定在 eth0 上,那么我們就可以把虛擬 IP 綁定在 eth0:0 上,這樣的話外界就能正常訪問此虛擬 IP 了,如果 master 掛掉了,keepalived 會讓此 master 的 eth0:0 端口失效,同時讓新 master 的 eth0:0 綁定虛擬 IP,這樣就避免了對外暴露兩個虛擬 IP。
再來看第二位問題,虛擬 IP 在某臺機器生效后,為啥要發一個 ARP 請求呢,這個問題其實在之前的文章中提到過,這里為了照顧其他沒看過之前文章的讀者,再簡單提一下,其實上面的架構圖我們作了一定程度的簡化,更詳細的應該如下圖所示
如圖示,三臺 LVS 機器組成一個同一網段的以太網我們知道,以太網是以 mac 地址來尋址的,我們知道現在對外暴露的是虛擬 IP,那么當帶有虛擬 IP 的包到達路由器時,它該怎么找到對應的機器呢?
一開始它啥也不知道,所以它在網址發了一個 ARP 廣播包,相當于大吼一聲:IP 地址為 115.205.4.213 的機器是誰啊,由于這個虛擬 IP 在 L1 上,所以只有 L1 響應了,L1 會把帶有自己 mac 地址的響應包發回給路由器,路由器收到后會把 IP 地址與 L1 mac 地址的關系記在本地,然后在包的頭部裝上 L1 的 mac 地址發給交換機,交換機就能識別到應該發給 L1,下次當客戶端再次發數據包到路由器時,路由器會首先在本地緩存(ARP 緩存)中查到 IP 對應的 mac(即 L1 的mac),命中后將包上的 mac 地址替換成 L1 的 mac 轉發出去,至此相信你應該明白為啥虛擬 IP 生效后要發 ARP 報文了,就是為了更新由器上的 ARP 緩存,將虛擬 IP 對應的 mac 地址更新為競選 master 成功的 backup 上的 mac,這樣下次路由器就能正確將新 master 的 mac 附在數據包上,就能正確地轉發到機器上了,否則,數據包會轉發到老的 master 上,引起災難性的后果!
問題二:幾臺機器首次啟動后,誰為 master,誰為 backup
這個問題其實很簡單,誰的能力強,誰就優先成為 master,我們可以給各個機器設置不同的值為 0~255 的權重,權重越大,代表此機器越有可能成為 master(如果權重一樣,則比較它們的 IP,IP 大的權重高),這里分幾種情況
-
每個機器啟動后都處于 Initialize 狀態,若某臺機器接口(eth0)Up 之后,如果其權重為 255 且此時還沒有 master 則其成為 master 并且讓虛擬 IP 綁定在 eth0:0 端口上,如果此時已有 master 呢,分兩種模式:搶占和非搶占模式,如果處于非搶占模式下,則它轉為 backup 狀態,否則它會重新競爭成為 master,此時一般能競爭成功,因為它處于最高權重(一般只有一臺機器處于最高權限)
-
如果某臺機器權重不為 255,則經過一段時間后如果此時還沒有 master ,那么它會競爭 master,如果此時有了 master,也和情況 1 一樣,分搶占和非搶占模式,為啥要經過一段時間才競爭 master 呢,其實主要是為了優先讓權重為 255 的機器成為 master
問題三: master 宕機后,backup 是如何感知到的,多臺 backup 又是如何競選出主機的
當機器成為 master 后,它會定時發送廣播給其他的 backup,讓其他 backup 知道它還存活著,如果在指定時間內(一般我們稱此時間為 Master_Down_Interval)backup 沒有收到 master 的廣播包,那么 backup 互相之間會發廣播包通過比較權重競爭 master,某臺 backup 競選 master 成功后同樣會讓虛擬 IP 綁定在 eth0:0 端口上,并且發送 ARP 包讓路由器等更新自己的 ARP 緩存,其他競選失敗的則轉為 backup 狀態
至此相信大家已經明白了 keepalived 的工作機制,所有上面說的這些工作只要配置一下 keepalived 的配置文件并啟動后即可實現。
另外 keepalived 實現的高可用機制不光可以用在 LVS 上,也可以用在 MySQL 等高可用上,所以你內部工程連 MySQL 的地址一般是虛擬 IP。現在我相信你能看懂如下 LVS 的高可用工作圖了
注:不管是 master 還是 backup 都能對背后的 RS 作健康檢查哦
總結
相信大家看完本文對 keepalived 的工作原理應該是了然于胸了,它的主要工作模式無非就兩塊:「健康檢查」和「高可用」,健康檢查我們只介紹了常見的兩種,其實它還支持通過運行腳本來作健康檢測,只是不太常用而已,另外 keepalived 的高可用可以說是大放異彩,除了用在 LVS 的高可用,還用在 Nginx ,MySQL 的高可用上,原理其實無非就是利用心跳檢測+競爭 master + IP 漂移來實現,完整的 keepalived.conf 配置文件大家有興趣可以看文末的參考鏈接,相信經過上面的原理講解再去看此文件不是問題
另外不知大家是否注意到了,master 雖然可以定時向 backup 發送心跳,但如果此心跳鏈路壞了 backup 就會誤認為 master 已經不可用了,從而去申請成為 master,這樣就會造成兩個 master 的出現,也就是我們常說的腦裂,怎么解決?可以同時用兩條心跳線路,這樣一條心跳檢測線路壞了,另一條還是好的,依然能傳送心跳消息。當然除了心跳鏈路壞了還有可能會有其他情況也會導致腦裂的發生,我們還是要做好多種預案,必要時人工及時介入,(關于腦裂的更多信息可以看文末的參考鏈接)
-
負載
+關注
關注
2文章
577瀏覽量
34492 -
IP
+關注
關注
5文章
1718瀏覽量
149970 -
LVS
+關注
關注
1文章
36瀏覽量
9972
原文標題:負載均衡之備胎轉正
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
常見的lvs負載均衡算法
燃料電池測試負載的工作原理是什么?
常用的服務器負載均衡多少錢一臺?
確保網站無縫運行:Keepalived高可用與Nginx集成實戰
![確保網站無縫運行:<b class='flag-5'>Keepalived</b>高可用與Nginx集成實戰](https://file1.elecfans.com/web3/M00/00/12/wKgZO2dGcZOAFKfHAABeakMUbaM263.png)
多鏈路負載均衡設置在哪里?
華納云:什么是負載均衡?優化資源利用率的策略
天翼云彈性負載均衡介紹
![天翼云彈性<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>介紹](https://file1.elecfans.com/web1/M00/F3/B3/wKgZoWcbVQWAO4EMAAAU9PSyED8191.png)
IPVS負載均衡原理解析
負載均衡是什么意思?盤點常見的三種方式
負載均衡服務由幾部分組成?分別是什么
如何利用traceroute命令發現網絡中的負載均衡
![如何利用traceroute命令發現網絡中的<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>](https://file1.elecfans.com/web2/M00/01/08/wKgZomazHumAVVonAAAqjCv-RWI311.png)
視頻網站服務器的四種負載均衡技術
回饋電子負載的工作原理、優點和應用
![回饋電子<b class='flag-5'>負載</b>的<b class='flag-5'>工作原理</b>、優點和應用](https://file1.elecfans.com//web2/M00/C2/57/wKgaomXdqgKAUAJsAAAyqigEJI033.webp)
評論