如何基于 DNS 权重实现读写流量分钟级切换?
解读
在国内生产环境中,CouchDB 集群往往跨可用区部署,读写域名分离(如 couch-rw.xxx.com 与 couch-ro.xxx.com)。当需要分钟级切换时,传统改代码、重启应用的方式已无法满足 SLA。利用DNS 权重(Weighted RR)可以在不重启应用、不改配置的前提下,把流量瞬间导向新节点。核心思路是:把“读写域名”分别指向多条 A/AAAA 记录,每条记录赋予不同权重;通过云解析 API 动态调权,实现秒级生效、分钟级收敛。
知识点
- CouchDB 多主复制:任一节点都可读写,但业务层通常把“写”集中到主可用区,避免冲突。
- DNS 权重记录:阿里云、腾讯云、华为云均支持同一子域名下多条 A 记录,权重 1–100,0 表示下线。
- TTL 策略:国内主流云解析最低 TTL 可设为 10 秒,配合客户端短连接,可实现分钟级收敛。
- 健康检查与兜底:利用云解析自带的故障切换或自建Consul-Template + DNS-API,权重先降到 0,再确认节点无连接,完成优雅下线。
- Java/Go 客户端缓存:JVM 默认缓存 DNS 30 s,需在启动参数加 -Dsun.net.inetaddr.ttl=10;Go 从 1.20 起默认尊重 TTL,无需改动。
- 双域名隔离:读写域名分离后,只切换写域名即可保证读流量零抖动;若需整体切流,同时调权两条域名。
答案
步骤如下,全程不超过 5 分钟:
-
前置准备
a. 为每个 CouchDB 节点申请内网 SLB 或固定内网 IP,并注册到 DNS。
b. 在云解析创建两条子域名:
couch-rw.xxx.com 与 couch-ro.xxx.com,均添加多条 A 记录,初始权重按容量比例分配(如主可用区 80,备 20)。
c. 设置统一 TTL=10 秒,并开启解析量统计,方便回滚时核对。 -
切换流程(以主可用区故障为例)
① 评估:监控发现主节点写延迟 >5 s,且持续 2 分钟,触发切换脚本。
② 预检查:脚本通过 /_up 接口确认备节点状态 200、集群 membership 正常。
③ 调权:调用云解析 API,把主可用区对应 A 记录权重置 0,备可用区权重置 100;API 返回 RequestId 即生效。
④ 观察:通过 netstat/ss 观察旧节点 5984 端口连接数,30 秒内从 2 k 降到 50 以内,即视为流量已切走。
⑤ 业务验证:写一条带 uuid 的测试文档到 couch-rw.xxx.com,确认 201 Created 且能在备节点立即查到。
⑥ 通知:飞书/钉钉群推送“DNS 权重切换完成,新主可用区=xx,旧主已下线”。 -
回滚
故障恢复后,反向执行调权脚本,把权重恢复为原比例;观察 2 分钟无异常后,标记事件关闭。 -
踩坑提醒
- VPN/长连接:部分运维长连接不遵守 TTL,需主动 kill 旧连接或重启跳板机。
- 浏览器缓存:后台管理系统若用浏览器直连,需强制刷新或改 host 临时验证。
- 私有 DNS:若公司用自建 BIND,需开启rndc reload,否则权重变更不会推送。
拓展思考
- 权重+延迟混合策略:在 DNS 权重基础上,再嵌入延迟探测(如阿里云“智能解析”),让华南用户始终访问深圳节点,华东访问上海,权重只在同地域内生效,异地多活更精细。
- Service Mesh 下沉:如果业务已上 Istio,可把 DNS 权重下沉到VirtualService 的 weighted route,实现秒级 100% 切换,无需改 DNS,但需引入 sidecar 运维成本。
- 双写校验:金融场景下,切流后让旧节点继续只读模式运行 24 h,通过_changes feed 与新区间做哈希校验,确保零数据丢失,再彻底下线。