基于Nomad实现双服务器故障转移的技术咨询
问题解答
1. Nomad是否适用于该场景?
完全适用。Nomad支持Docker容器化任务的调度与故障转移,无需修改业务代码就能实现主备模式的服务部署,刚好匹配本地部署、主备故障转移的需求,针对需要避免重复处理的视频流服务场景,Nomad的调度约束和部署规则可以精准控制服务的运行位置。
2. 如何通过Nomad实现需求?
第一步:修正Nomad集群配置(解决当前故障无反应的核心问题)
你当前配置里的bootstrap_expect = 2是关键问题:Raft协议要求集群达成**法定人数(quorum)**才能选举leader,2个节点的集群quorum为2,主服务器宕机后仅剩1个节点,无法满足quorum要求,无法成为leader,自然无法调度任务。
修改两台服务器的server配置:
# 两台服务器的server块统一修改为 server { enabled = true bootstrap_expect = 1 # 改为1,允许单节点完成集群初始化 server_join { retry_join = [ "192.168.1.38", "192.168.1.20", ] retry_max = 0 retry_interval = "15s" } }
注:bootstrap_expect设为1后,初始启动时单节点即可完成集群初始化,后续加入第二节点会自动形成多节点集群;主节点宕机后,备用节点能自动成为leader,获得调度能力。
第二步:配置作业的主备调度策略
针对两个服务,通过Nomad作业的约束和部署规则,实现仅主节点运行服务,主节点故障后自动切换到备用节点:
VA Service示例作业配置
job "va-service" { datacenters = ["dc1"] type = "service" group "va" { count = 1 # 确保仅运行一个实例,避免重复处理视频流 # 硬约束:优先强制调度到主节点 constraint { attribute = "${node.name}" operator = "=" value = "server1" } # 软约束:主节点不可用时,允许调度到备用节点 constraint { attribute = "${node.name}" operator = "=" value = "server2" hard = false } task "va" { driver = "docker" config { image = "your-va-service-image:latest" ports = ["http"] } service { name = "va-service" port = "http" } } } }
Client Service作业配置(逻辑一致)
只需将约束中的value对应调整,同样设置count=1和主备节点的约束规则,确保Client Service跟随主节点故障转移。
关键配置说明
count = 1:严格控制服务实例数量,避免重复处理流数据- 硬约束+软约束组合:优先绑定主节点,主节点离线时自动切换到备用节点
service类型作业:Nomad会自动监控节点健康状态,主节点故障后自动在备用节点启动服务
第三步:验证故障转移流程
- 启动两台Nomad服务器和客户端,执行
nomad server members确认集群状态正常 - 提交作业,执行
nomad job status <job-name>确认服务仅在主节点(server1)运行 - 关闭主服务器,等待30-60秒(Nomad默认节点健康检查超时),再次执行
nomad job status <job-name>,确认服务已在备用节点(server2)启动 - 若需要恢复主节点后自动切回,可添加亲和性规则:
affinity { attribute = "${node.name}" value = "server1" weight = 100 # 权重越高,越优先调度到该节点 }
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

