keepalived 實現 Java 服務的高可用(主備切換)

前言

本文要說的是基於 keepalived 實現兩臺服務器之間的主備切換,從而實現 Java 服務的高可用。keepalived 的原理很少作介紹,自行搜索瞭解,keepalived 的安裝部署請參考 keepalived 的安裝及使用java

我的建議web

不要沉迷於 死扣 和 理解 原理,網上關於原理的文章大同小異,關鍵詞就是 虛擬ip,瞭解個大概,動手實踐下,結合 keepalived 的配置文件會更好。shell

項目描述

我所作的項目是否是一個 web 程序,主要功能是定時從文件服務器下載文件,而後作一些處理,放到本地。bash

需求

當一臺服務器部署的系統出現故障時,可以有備用機器繼續提供服務,儘可能避免人工介入去恢復系統。注意跟負載均衡的區別!初步方案只提供一臺備用機。服務器

方案

1. 實現原理

keepalived 的配置文件中有 權重STATE 兩個配置項,兩臺機器上的 keepalived 經過 虛擬IP 綁定以後,它們之間就能夠經過上述的配置項來進行 」選舉「 ,區分 MASTERBACKUP負載均衡

而後配合 keepalived 中另外的兩個功能,檢測腳本通知腳本 實現咱們的主備切換的需求。優化

到底如何決定 MASTER 和 BACKUP ?.net

STATE 的值能夠是 MASTERBACKUP,當 兩臺機器配置的 STATE 的值相同,而且權重相同時,誰先啓動誰是 MASTER,當兩臺機器的配置的 權重 相同時,state 爲 MASTER 的那臺機器最終會成爲 MASTER(哪怕這臺機器啓動的時間比另外一臺晚)日誌

檢測腳本的做用code

對咱們的使用場景來講,檢測腳本的做用有兩個,一是檢測咱們的 java 進程是否存在,二是對 keepalived 的權重進行加減。好比: 檢測到咱們的 java 進程關閉了,咱們就能夠下降這臺機器的權重。

權重改變是永久生效的嗎?

否, 權重的增長或者下降只對當前一輪的檢測有效!下次檢測開始還會恢復到配置的默認值。

通知腳本的做用

通知腳本有兩種,分別根據 keepalived 的狀態去觸發。對咱們的使用場景來講,這兩種分別是: **一個是當這臺機器是 MASTER 時須要觸發的腳本,二是當這臺機器是 BACKUP 的時候須要觸發的腳本。**好比: 當咱們的機器變成 MASTER 時,去啓動咱們的 java 進程。

2. 具體配置

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 啓動時),纔會觸發對應的通知腳本。

執行流程

  1. 首先是準備兩臺機器好比 Server A 和 Server B,分別部署咱們的 java 應用keepalived,甚至其餘可能用到的服務,好比咱們項目中用的文件同步。

  2. 分別啓動兩臺機器的 keepalived 進程,順序無所謂,配置文件都同樣,誰先啓動誰就是 master。

  3. 好比 Server A 是 MASTER,keepalived 就會去觸發咱們的通知腳本(notify_master),通知腳本就會建立一個文件標記這臺機器是 master,同時啓動咱們的 java 進程。Server B 的 keepalived 啓動後,觸發 notify_slave, 結合腳本所作的事情,咱們發現,第一次觸發並不會形成什麼影響,甚至後續咱們能夠優化一下,減小這些無用功。

  4. 當咱們關閉 Server A 的 java進程,檢測腳本檢測到 java 進程關閉了,而且當前主機是 MASTER (由於檢測到 master.flag 文件存在),檢測腳本就會返回 1,導致 Server A 的權重下降 20,也就是比 Server B 低20,此時會在此進行 「選舉」,Server A 就變成了 backup,同時去觸發notify_slave腳本,Server B 就變成了 master, 同時觸發 notify_master腳本。

  5. 根據兩個腳本作的事情,咱們最終發現,兩臺機器不只發生了身份切換,而且作的事情也對換了一下。

幾個問題

  • keepalived 的日誌存放位置 : /var/log/messages
  • 若是發現兩邊都能檢測到虛擬ip,請檢查下 防火牆是否沒有關閉!
  • 檢測腳本和通知腳本的執行順序: 同時執行! 這也是我爲何加了 master.flag 的緣由。 請仔細體會!

總結

上述僅僅是一個 demo 方案,並未通過生產環境的考驗,須要打磨的地方不少。另外就是網上作此類方案的案例不多,多是應用不到吧,其餘大多方案都是,kill 掉 keepalived 從而完成主備切換。寫這篇文章的主要緣由是本身在作的過程當中,有不少疑惑,網上沒直接給出答案,其實正常操做的話不會有我這些疑惑,我是由於腳本寫錯了,在我堅決腳本沒問題的時候,去懷疑一些問題,好比權重改變後就永久生效了,通知腳本是根據你的狀態一直在執行的!

​ --- 有點兒` 菜!

最後歡迎你們指出其中的問題,或者作一些補充!! 謝謝

相關文章
相關標籤/搜索