这是学习笔记的第 2092 篇文章
最近在梳理Consul健康检查逻辑的时候,也发现了一些潜在的问题,这些问题虽然不会直接造成业务故障,但是在故障发生的时候还是存在较高的概率导致一些意料之外的影响。
从解耦的设计思路来看,我们希望很多事情能够做到多重校验,即设计一个组件的时候,如何涉及外部环节,我们需要从故障设计的角度来进行考量,即认为我们的服务或者组件是存在故障的风险,按照这个来设计,就能够导致一些后续设计中的尴尬。
对于Consul的逻辑检查,说简单也可以,说复杂确实需要补充很多的内容,以下是在之前整理的一版基础上进行细化得到的。
整体上脚本分为两个部分,第一个部分是判断数据库的角色,第二个部分根据读写策略进行补充。
数据库角色判断的逻辑如下:
第二个部分是根据角色和读写策略完成健康检查,如果正常返回0,否则返回2
我来做一下解释,目前的读写分离如果是主库,则为write,如果是查询操作主从库均可读,则为Mixed_Read,如果查询只在从库可行,则为Read_only.
在这个基础上我们来梳理一下这种策略的潜在风险。
既然设置了健康检查,我们就不能指望服务状态始终不变,如果发生了服务宕机,在服务重启后,如果因为健康检查策略导致主从混写,那这个问题就严重了。
所以在目前的检查模式下,如果主库宕机,在重启服务前需要暂时停止健康检查逻辑,否则就会造成数据错乱的严重问题。
如果从库宕机,则健康检查逻辑还是比较稳定,除了原本的读混合模式会漂移到主库之外,其他的部分没有变化。
如果是主从复制失败,则问题依然是可控的。
做完这些分析之后,我觉得目前的健康检查逻辑是存在潜在风险的,因为有些环节需要依赖人工的检查,因为一旦失误,就会造成数据问题。所以在这一点上我觉得健康检查的逻辑需要进行补充和整改。
我们可以换一个角度来考虑,就是什么时候应该会发生健康检查状态的变化,目前梳理了下主要有以下几种。
除非主库宕机,其实我们是不希望域名频繁的做切换的,如果发生切换,主要有两个场景,一个是异常宕机,另外一个就是基于ACL的key-value检测。
从这个角度来看,域名服务是相对恒定的,实时的检测其实都对于每一次检测都是实时的,如果出现超时,连接异常等情况,其实是尽可能希望在当前域名范围内处理,毕竟这个时候域名和IP仅仅的连接的形式不同而已,如果要建立更加稳定的健康检查,应该是ACL+实时检测组合的方案,基本思路就是ACL检测优先,在服务故障切换之后,会补充检测健康检查的逻辑,把这两个部分整合起来处理,就会避免那些意料之外的异常域名切换。