本文要说的是基于 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 从而完成主备切换。写这篇文章的主要缘由是本身在作的过程当中,有不少疑惑,网上没直接给出答案,其实正常操做的话不会有我这些疑惑,我是由于脚本写错了,在我坚决脚本没问题的时候,去怀疑一些问题,好比权重改变后就永久生效了,通知脚本是根据你的状态一直在执行的!
--- 有点儿` 菜!
最后欢迎你们指出其中的问题,或者作一些补充!! 谢谢