keepalived 实现 Java 服务的高可用(主备切换)
时间: 2019-12-04来源:OSCHINA
前景提要
「深度学习福利」大神带你进阶工程师,立即查看>>>
前言
本文要说的是基于 keepalived 实现两台服务器之间的 主备切换 ,从而实现 Java 服务的高可用。 keepalived 的原理不多做介绍,自行搜索了解, keepalived 的安装部署请参考 keepalived 的安装及使用 。
个人建议
不要沉迷于 死扣 和 理解 原理,网上关于原理的文章大同小异,关键词就是 虚拟ip ,了解个大概,动手实践下,结合 keepalived 的配置文件会更好。
项目描述
我所做的项目是不是一个 web 程序,主要功能是定时从文件服务器下载文件,然后做一些处理,放到本地。
需求
当一台服务器部署的 系统出现故障 时,能够有 备用机器 继续提供服务,尽量避免人工介入去恢复系统。注意跟 负载均衡 的区别!初步方案只提供一台备用机。
方案
1. 实现原理
keepalived 的配置文件中有 权重 和 STATE 两个配置项, 两台机器 上的 keepalived 通过 虚拟IP 绑定之后,它们之间就可以通过上述的配置项来进行 ”选举“ ,区分 MASTER 和 BACKUP 。
然后配合 keepalived 中另外的两个功能, 检测脚本 和 通知脚本 实现我们的主备切换的需求。 到底如何决定 MASTER 和 BACKUP ?
STATE 的值可以是 MASTER 和 BACKUP ,当 两台机器配置的 STATE 的值相同,并且权重相同时,谁先启动谁是 MASTER ,当两台机器的配置的 权重 相同时,state 为 MASTER 的那台机器最终会成为 MASTER (哪怕这台机器启动的时间比另一台晚) 检测脚本的作用
对我们的使用场景来说,检测脚本的作用有两个, 一是检测我们的 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 启动时),才会触发对应的通知脚本。
执行流程 首先是准备两台机器比如 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 脚本。 根据两个脚本做的事情,我们最终发现,两台机器不仅发生了身份切换,并且做的事情也对换了一下。
几个问题 keepalived 的日志存放位置 : /var/log/messages 如果发现两边都能检测到虚拟ip,请检查下 防火墙是否没有关闭! 检测脚本和通知脚本的执行顺序: 同时执行! 这也是我为什么加了 master.flag 的原因。 请仔细体会!
总结
上述仅仅是一个 demo 方案,并未经过生产环境的考验,需要打磨的地方很多。另外就是网上做此类方案的案例很少,可能是应用不到吧,其他大多方案都是, kill 掉 keepalived 从而完成主备切换。写这篇文章的主要原因是自己在做的过程中,有很多疑惑,网上没直接给出答案,其实正常操作的话不会有我这些疑惑,我是因为脚本写错了,在我坚定脚本没问题的时候,去怀疑一些问题,比如 权重改变后就永久生效了,通知脚本是根据你的状态一直在执行的!
​ --- 有点儿` 菜!
最后欢迎大家指出其中的问题,或者做一些补充!! 谢谢

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行