最近和同事梳理了下高可用方案的一些细节,对于我来说,如果能够提前发现一些潜在的问题,那对于我们来说收益是最大的,毕竟高可用方案是我们发起的,一旦出现了不可用,不管出于何种原因,都算是我们工作的失职,在这个过程中也发现了一些过度设计的问题。
我们现在在力推基于Consul的域名服务,同时也提供了基于ACL的服务,整体上看是这样的数据关系。
对于Consul来说,一个重要的文件就是健康检查脚本了,这个脚本的魅力就在于它的威力,如果注册了域名A,但是健康检查失败了,那么这台服务器相关的域名解析都会失效,会根据负载均衡策略漂移到另外的节点上,这是一个动态的处理过程。
但是目前的实现方式存在一些逻辑的隐患。
目前健康检查中是依赖了ACL机制,如果ACL检查失败,则域名解析会直接失败。 这个问题会造成一种困境,那就是因为运维操作导致ACL注册错误->健康检查失败->域名解析失败->业务不可用。
而归根节点,业务是否关系这个ACL的配置,目前来看是否定的,而且这个配置是一个相对固定的配置,除非触发切换,是不大可能频繁变更的。
ACL的配置既然如此敏感,那么我们是不能100%保证不出问题的,同时还是CMDB,这些配置都有可能出现失误,只要涉及到人的操作,都有这种可能。所以因为业务不关心的一个属性导致业务关心的高可用产生了问题,就实在不应该了。所以我们可以果断去除健康检查中基于ACL的检测,而应该把这些机制锁定在本机检测,换句话说,内部的服务还需要依赖外部的服务,有些本末倒置。
但是如果单纯按照show slave hosts,复制用户去锁定是否为Master,这个逻辑也是不完整的。比如故障出现的时候,从库先宕机了,那么健康检查就会导致主库检查失败,导致域名不可用,看起来是一个不合理的逻辑,从库宕机或者复制失败,导致主库不可用。
所以我们讨论了下,梳理了如下的检查逻辑,能够基本保证这个逻辑检查的完整性,当然有些细节没有展开,比如延时,域名的负载均衡等。
而整体的逻辑能够通用,这样在检查的时候就可以避免定制化,差异化的配置,能够统筹管理起来。