问题场景:非常重要带状态服务,经常出现机器硬件故障,需要运维手动切换备机,修改配置,反应速度慢。
想过解决方案:
1. 一致性hash,目前使用zk临时节点方案有些问题。像如果机器因为网络不稳定掉线,Zookeeper Client在触发Session Expried 事件时,无法确定已经掉线多长时间了,可能已经掉线一个小时了,这会网络恢复,机器自动加入集群,Y的又会造成一波不稳。方案的前提,与zk server 的网络状况要很稳定,但实际很难达到要求。
2. 热备自动切换,Windows下方案基本是收费的,而且多是双机热备,实际备机只有1/10的样子。
3. 去状态,将状态数据集中处理,改动大
需要的是最小的改动,实现快速可靠容灾,想到了IP切换,修改IP不需要同步服务调用的路由表。
Window 下可以使用系统调用,AddIPAddress,DeleteIPAddress函数实现添加删除IP地址:
DWORD AddIPAddress(
_In_ IPAddr Address,
_In_ IPMask IpMask,
_In_ DWORD IfIndex,
_Out_ PULONG NTEContext,
_Out_ PULONG NTEInstance
)DWORD DeleteIPAddress(
_In_ ULONG NTEContext
);Remarks
The AddIPAddress function is used to add a new IPv4 address entry on a local computer. The IPv4 address added by the AddIPAddress function is not persistent. The IPv4 address exists only as long as the adapter object exists. Restarting the computer destroys the IPv4 address, as does manually resetting the network interface card (NIC). Also, certain PnP events may destroy the address.
这种IP改动是临时性的,而且方法调用后立即生效,当服务器重启,或网卡重启都设置都会失效。这种特性也适合我们的场景,切换只需要临时性的,监控工具临时性的将IP抢过来,后期运维人员修改路由之后,就可以将IP地址删除了。
这个IP切换过程也是安全的,上一篇中说到的: IP冲突-- Gratuitous ARP ,AddIPAddress 方法在IP冲突的时候是无法设置成功的,也就是说只有机器真实的不可用时IP才会发生切换。原有机器再起来也不会发生IP冲突问题造成两台都不可用情况。
因此实现就很简单了:
监控:一个备机部署一个服务,监控N台服务器,采用ping的方式,当一段时间内ping全部失败,并且再ping网关OK,说明那台机器宕机。
切换:检测到宕机情况,使用AddIPAddress 设置到设定的网卡中即可。同时屏蔽其他失败切换请求。
恢复:运维发现宕机机器恢复,可通过工具调用DeleteIPAddress 删除抢到的IP地址,在启动宕机机器,恢复服务。
此种方案简单、不易出错,但只能适应与Windows之间。
如果有linux机器参与、那就需要另外监控并解决IP冲突问题了。