知识卡片
高可用设计:要写清楚"哪里会丢",而非假装100%可靠
内容
消息队列案例的高可用详细设计分三层,每一层都没有回避自己的极限失败场景,而是明确写出”在什么条件下会丢消息、丢了之后怎么办”。消息发送可靠性:业务服务器嵌入消息队列SDK,SDK支持轮询发送,当某个分组的主服务器无法发送时,SDK挑选下一个分组主服务器重发,依次尝试所有主服务器直到发送成功;如果全部主服务器都无法发送,SDK可以缓存消息也可以直接丢弃,具体策略由启动时的配置指定——但如果SDK缓存了未发送的消息、此时业务服务器又重启,缓存消息将永久丢失,这种情况SDK不做处理,业务方需要针对非常关键的消息自己实现永久存储功能。消息存储可靠性:消息存储在MySQL中,每个分组一主一备两台服务器,之间通过复制来保证存储高可用;但如果主备间出现复制延迟,恰好此时主服务器宕机导致数据无法恢复,部分消息会永久丢失,这种情况同样不做针对性设计,而是要求DBA监控主备复制延迟,超过30秒就及时告警处理。消息读取可靠性:每个分组一主一备,主服务器同时支持发送和读取,备服务器只支持读取;正常情况下备服务器不对外提供服务,只有备服务器判断主服务器故障时才对外提供读取服务;主备角色和分组信息通过配置指定,具体通过ZooKeeper做状态判断和决策——主备服务器启动时分别连接ZooKeeper,在/MQ/Server/[group]目录下建立EPHEMERAL临时节点(例如分组group1对应/MQ/Server/group1/master和/MQ/Server/group1/slave),节点超时时间可配置,默认10秒。这三段设计共同体现了一个写文档的重要原则:高可用设计不是宣称”绝对不丢数据”,而是老老实实分析出系统在哪些具体条件下会丢数据、丢多少、由谁(SDK自动处理还是业务方自己兜底、还是靠DBA人工监控)来兜底这个风险,把”不可能100%可靠”这件事说清楚,比空喊一个不可能兑现的可用性指标更有工程价值。