非同步操作和輪詢

預設情況下playbook中的任務執行時會一直保持連線,直到該任務在每個節點都執行完畢.有時這是不必要的,比如有些操作執行時間比SSH超時時間還要長.

解決該問題最簡單的方式是一起執行它們,然後輪詢直到任務執行完畢.

你也可以對執行時間非常長(有可能遭遇超時)的操作使用非同步模式.

為了非同步啟動一個任務,可以指定其最大超時時間以及輪詢其狀態的頻率.如果你沒有為 poll 指定值,那麼預設的輪詢頻率是10秒鐘:

---

- hosts: all
  remote_user: root

  tasks:

  - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
    command: /bin/sleep 15
    async: 45
    poll: 5

Note

async 並沒有預設值,如果你沒有指定 async 關鍵字,那麼任務會以同步的方式執行,這是Ansible的預設行為.

另外,如果你不需要等待任務執行完畢,你可以指定 poll 值為0而啟用 “啟動並忽略”

---

- hosts: all
  remote_user: root

  tasks:

  - name: simulate long running op, allow to run for 45 sec, fire and forget
    command: /bin/sleep 15
    async: 45
    poll: 0

Note

對於要求排它鎖的操作,如果你需要在其之後對同一資源執行其它任務,那麼你不應該對該操作使用”啟動並忽略”.比如yum事務.

Note

--forks 參數值過大會更快的觸發非同步任務.也會加快輪詢的效率.

當你想對 “啟動並忽略” 做個變種,改為”啟動並忽略,稍後再檢查”,你可以使用以下方式執行任務:

---
# Requires ansible 1.8+
- name: 'YUM - fire and forget task'
  yum: name=docker-io state=installed
  async: 1000
  poll: 0
  register: yum_sleeper

- name: 'YUM - check on fire and forget task'
  async_status: jid={{ yum_sleeper.ansible_job_id }}
  register: job_result
  until: job_result.finished
  retries: 30

Note

如果 async: 值太小,可能會導致 “稍後檢查” 任務執行失敗,因為 async_status:: 的臨時狀態檔案還未被寫入資訊,而”稍後檢查”任務就試圖讀取此檔案.

See also

Playbooks
An introduction to playbooks
User Mailing List
Have a question? Stop by the google group!
irc.freenode.net
#ansible IRC chat channel