本文要說的是基於 keepalived 實現兩臺服務器之間的主備切換,從而實現 Java 服務的高可用。keepalived 的原理很少作介紹,自行搜索瞭解,keepalived 的安裝部署請參考 keepalived 的安裝及使用 。java
我的建議web
不要沉迷於 死扣 和 理解 原理,網上關於原理的文章大同小異,關鍵詞就是 虛擬ip,瞭解個大概,動手實踐下,結合 keepalived 的配置文件會更好。shell
我所作的項目是否是一個 web 程序,主要功能是定時從文件服務器下載文件,而後作一些處理,放到本地。bash
當一臺服務器部署的系統出現故障時,可以有備用機器繼續提供服務,儘可能避免人工介入去恢復系統。注意跟負載均衡的區別!初步方案只提供一臺備用機。服務器
keepalived 的配置文件中有 權重 和 STATE 兩個配置項,兩臺機器上的 keepalived 經過 虛擬IP 綁定以後,它們之間就能夠經過上述的配置項來進行 」選舉「 ,區分 MASTER 和 BACKUP 。負載均衡
而後配合 keepalived 中另外的兩個功能,檢測腳本 和 通知腳本 實現咱們的主備切換的需求。優化
到底如何決定 MASTER 和 BACKUP ?.net
STATE 的值能夠是 MASTER 和 BACKUP,當 兩臺機器配置的 STATE 的值相同,而且權重相同時,誰先啓動誰是 MASTER,當兩臺機器的配置的 權重 相同時,state 爲 MASTER 的那臺機器最終會成爲 MASTER(哪怕這臺機器啓動的時間比另外一臺晚)日誌
檢測腳本的做用code
對咱們的使用場景來講,檢測腳本的做用有兩個,一是檢測咱們的 java 進程是否存在,二是對 keepalived 的權重進行加減。好比: 檢測到咱們的 java 進程關閉了,咱們就能夠下降這臺機器的權重。
權重改變是永久生效的嗎?
否, 權重的增長或者下降只對當前一輪的檢測有效!下次檢測開始還會恢復到配置的默認值。
通知腳本的做用
通知腳本有兩種,分別根據 keepalived 的狀態去觸發。對咱們的使用場景來講,這兩種分別是: **一個是當這臺機器是 MASTER 時須要觸發的腳本,二是當這臺機器是 BACKUP 的時候須要觸發的腳本。**好比: 當咱們的機器變成 MASTER 時,去啓動咱們的 java 進程。
keepalived 的配置文件
! Configuration File for keepalived # 全局配置 global_defs { router_id LVS_MS vrrp_skip_check_adv_addr vrrp_garp_interval 0 vrrp_gna_interval 0 } # 配置檢測腳本,腳本名稱隨意 vrrp_script chk { script "/etc/keepalived/chk.sh" # 檢測腳本的位置 interval 3 # 每隔 3 秒執行一次 weight -20 # 權重 -20 ,根據檢測腳本的返回值去判斷是否要減掉 } # vrrp 實例 vrrp_instance VI_1 { state BACKUP # 主備配置同樣,而且權重也同樣,這樣誰先啓動誰就是 MASTER interface eth0 virtual_router_id 90 priority 100 # 默認權重 advert_int 1 authentication { auth_type PASS auth_pass keepalived_ms } virtual_ipaddress { 172.16.10.90 # 虛擬 ip } # 引用檢測腳本,由於能夠配置多個 vrrp 實例,每一個實例均可以使用同一個檢測腳本 track_script { chk } # 配置通知腳本的路徑,腳本名稱隨意 # 1. 當 keepalived 的狀態爲 MASTER 時,會觸發這個通知腳本 notify_master "/etc/keepalived/notify.sh master" # 2. 與 1 相反 notify_backup "/etc/keepalived/notify.sh backup" }
檢測腳本
#!/bin/bash # 查找java服務進程個數 count=`ps aux | grep -v grep | grep 進程名稱 | wc -l` # master.flag 就是一個標記文件,若是文件存在,表示爲 master # 若是 MASTER 上的服務down 掉,下降權重 # 若是 MASTER 上的服務沒有問題,權重不變 # 若是是BACKUP ,權重保持不變 if [ -f master.flag ] && [ $count -eq 0 ]; then exit 1 # 結合 keepalived.conf 配置文件,這裏返回 1 表示當前機器權重 -20 else exit 0 # 返回 0 ,什麼也不作 fi
檢測腳本何時執行?
檢測腳本時定時執行的,時間能夠配置,並且主備兩臺機器都會同時執行。
通知腳本
#!/bin/bash # 接收參數, master 或者 backup 或者 "" function=$1 # 若是觸發的是 master 的通知腳本 if [ "x"$function = "xmaster" ] ; then # 1. 新建標記文件,標誌本機爲 MASTER touch master.flag # 2. 啓動 java 進程 # TODO # 3. 啓動文件同步服務 # TODO 這裏是由於個人項目須要,因此要開啓這樣一個服務 else # 1. 刪除 MASTER 標記,標記爲 BACKUP rm -f master.flag # 2. 關閉 java 進程 # TODO 爲了保險一點,再關閉一次 # 3. 關閉文件同步服務 # TODO fi
通知腳本何時執行?
只有當狀態發生切換時(包括 keepalived 啓動時),纔會觸發對應的通知腳本。
首先是準備兩臺機器好比 Server A 和 Server B,分別部署咱們的 java 應用 和 keepalived,甚至其餘可能用到的服務,好比咱們項目中用的文件同步。
分別啓動兩臺機器的 keepalived 進程,順序無所謂,配置文件都同樣,誰先啓動誰就是 master。
好比 Server A 是 MASTER,keepalived 就會去觸發咱們的通知腳本(notify_master),通知腳本就會建立一個文件標記這臺機器是 master,同時啓動咱們的 java 進程。Server B 的 keepalived 啓動後,觸發 notify_slave, 結合腳本所作的事情,咱們發現,第一次觸發並不會形成什麼影響,甚至後續咱們能夠優化一下,減小這些無用功。
當咱們關閉 Server A 的 java進程,檢測腳本檢測到 java 進程關閉了,而且當前主機是 MASTER (由於檢測到 master.flag 文件存在),檢測腳本就會返回 1,導致 Server A 的權重下降 20,也就是比 Server B 低20,此時會在此進行 「選舉」,Server A 就變成了 backup,同時去觸發notify_slave腳本,Server B 就變成了 master, 同時觸發 notify_master腳本。
根據兩個腳本作的事情,咱們最終發現,兩臺機器不只發生了身份切換,而且作的事情也對換了一下。
上述僅僅是一個 demo 方案,並未通過生產環境的考驗,須要打磨的地方不少。另外就是網上作此類方案的案例不多,多是應用不到吧,其餘大多方案都是,kill 掉 keepalived 從而完成主備切換。寫這篇文章的主要緣由是本身在作的過程當中,有不少疑惑,網上沒直接給出答案,其實正常操做的話不會有我這些疑惑,我是由於腳本寫錯了,在我堅決腳本沒問題的時候,去懷疑一些問題,好比權重改變後就永久生效了,通知腳本是根據你的狀態一直在執行的!
--- 有點兒` 菜!
最後歡迎你們指出其中的問題,或者作一些補充!! 謝謝