首页/系统与基础设施/自动化运维速查/剧本中的等待与轮询写法
Ansible 核心70 条

剧本中的等待与轮询写法

等待有两个手段:等待类模块在目标机侧轮询端口、路径或连接可用;任务级 retries/delay/until 由控制节点重复尝试。关键在于按实测定超时、用状态字段而非文本判定、只读探测声明无变更,并把等待失败当作中止信号。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​​​​‌​‌‌​‌​​‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌‌‌​‌‌​‌‌​​​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌‌‌​​‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

等待要有明确终点

变更之后常常需要“等它真的好了再继续”:服务进程起来了但端口还没 listen、数据库刚开始恢复、证书文件还没生成。Playbook 里等待有两条路:一是用专用等待模块让目标机自己轮询条件;二是对任务加重复尝试与间隔,由控制节点在每次尝试后重新判断。两者都要有超时与失败判定,否则等待就变成无限挂起。

基本信息

专用等待模块等待端口、路径、连接可用等条件,在目标机侧轮询
重复尝试任务级 retries 与 delay 控制尝试次数与间隔,until 定义成功条件
超时等待类模块自带超时参数,需按业务实际耗时设置,而不是默认值
连接就绪重启类操作后需要先等连接恢复,再继续后续任务
判定依据用状态字段而非文本片段判定成功,例如端口可连或返回码为 0
幂等要求轮询类任务不应产生变更,需显式声明无变更

典型使用场景

  • 重启服务后等端口就绪,再执行健康检查,而不是立刻探测
  • 重启主机后等连接恢复,避免后续任务因不可达而失败
  • 数据库初始化后等数据目录出现标志文件再继续
  • 集群成员逐个就绪:等每个节点上线后再推进下一个
  • 等待外部依赖(对象存储、注册中心)可用后继续部署
  • 等待长时间任务的产物出现,配合产物校验一起判定成功

两种等待写法

两种等待写法
- name: 重启应用
  ansible.builtin.service:
    name: "{{ svc_name }}"
    state: restarted
  notify: 等待端口就绪

# 写法一:等待类模块,在目标机侧轮询条件
- name: 等端口可连再继续
  ansible.builtin.wait_for:
    host: "{{ ansible_host | default('127.0.0.1') }}"
    port: "{{ app_port }}"
    delay: 3            # 先给进程一点启动时间
    timeout: 120        # 总超时,按业务实际耗时设定
    state: started

# 写法二:重复尝试,由控制节点判断成功条件
- name: 轮询健康检查直到通过
  ansible.builtin.uri:
    url: "http://127.0.0.1:{{ app_port }}/healthz"
    status_code: 200
  register: health
  until: health.status == 200
  retries: 12
  delay: 5
  changed_when: false   # 只读探测,不产生变更

- name: 重启主机后等连接恢复
  ansible.builtin.wait_for_connection:
    delay: 10
    timeout: 300

等待参数怎么定

参数作用取值思路
timeout总等待上限按最慢一次变更的实测耗时留出余量,不要用很大的固定值
delay首次检查前的等待给进程或服务留出启动缓冲,避免立刻失败
retries 与 delay尝试次数与间隔两者相乘即为最长等待,需与超时口径一致
判定条件什么算成功用状态字段与返回码,避免匹配易变的文本
无变更声明轮询不算变更只读探测类任务显式声明 changed_when: false
等端口不如等业务就绪:端口能连不代表服务能提供服务(连接池未建好、迁移未完成)。有健康检查接口时,优先探测它并校验返回内容,而不是只探测端口。
把超时设得过大,会让真正的故障以“等待超时失败”的形式晚很多才被发现;设得过小,则会在正常但较慢的环境里误判失败。参数应当来自实测数据,并允许按环境用变量覆盖。

失败后怎么办

等待失败意味着“预期状态没有出现”,此时应当直接中止后续变更,而不是继续往下推。把等待放在需要它的那一步之前,并让其失败消息说明探测目标与已等待时长,接警人才能第一时间判断是启动慢还是根本没起来。

易错点

  • 等待没有超时或超时极大,故障时任务长时间挂起,占用执行窗口且无人察觉
  • 只探测端口不校验业务就绪,后续任务在服务实际不可用时继续推进
  • 用文本片段匹配判定成功,日志措辞随版本变化后误判失败或误判成功
  • 轮询类任务未声明无变更,每次执行都报 changed,掩盖真实的配置变更
  • 重启主机后没有先等待连接恢复,后续任务集中报主机不可达,掩盖真正原因

数据来源与参考

  • Ansible 官方文档 ansible.builtin.wait_for 模块
  • Ansible 官方文档 ansible.builtin.wait_for_connection 模块
  • Ansible 官方文档 Loops and retries(until/retries/delay)

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/wait-until-polling-playbook.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​​​​‌​‌‌​‌​​‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌‌‌​‌‌​‌‌​​​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌‌‌​​‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​