Асинхронные действия и опрос
По умолчанию задачи в плейбуках блокируют выполнение, то есть соединения остаются открытыми до тех пор, пока задача не завершится на каждом узле. Это не всегда желательно, или же вы можете запускать операции, которые занимают больше времени, чем таймаут SSH.
Чтобы избежать проблем с блокировкой или таймаутом, вы можете использовать асинхронный режим для одновременного выполнения всех задач, а затем опросить их состояние, пока они не завершатся.
Чтобы запустить задачу асинхронно, укажите ее максимальное время выполнения и частоту опроса статуса. Значение опроса по умолчанию составляет 10 секунд, если вы не укажете другое значение для poll:
---
- 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
Примечание
По умолчанию нет ограничения времени для асинхронного выполнения. Если вы опустите ключевое слово «async», задача выполняется синхронно, что является по умолчанию в Ansible.
В качестве альтернативы, если вам не нужно ждать завершения задачи, вы можете запустить ее асинхронно, указав значение опроса 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
Примечание
Не следует пытаться выполнить задачу асинхронно, указав значение опроса 0, при работе с операциями, требующими взаимных исключений (например, транзакции yum), если вы ожидаете выполнения других команд в плейбуке с теми же ресурсами.
Примечание
Использование более высокого значения для --forks приведет к ещё более быстрому запуску асинхронных задач. Это также повышает эффективность опроса.
Если вы хотите выполнить задачу асинхронно и проверить ее позже, вы можете выполнить задачу, аналогичную следующей:
---
# Requires ansible 1.8+
- name: 'YUM - async task'
yum:
name: docker-io
state: installed
async: 1000
poll: 0
register: yum_sleeper
- name: 'YUM - check on async task'
async_status:
jid: "{{ yum_sleeper.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
Примечание
Если значение async: недостаточно высокое, это приведёт к ошибке задачи «проверить позже», потому что временный файл состояния, который ищет async_status:, не будет создан или больше не существует.
Если вы хотите запустить несколько асинхронных задач, ограничив количество одновременно выполняемых задач, вы можете сделать это так:
#####################
# main.yml
#####################
- name: Run items asynchronously in batch of two items
vars:
sleep_durations:
- 1
- 2
- 3
- 4
- 5
durations: "{{ item }}"
include_tasks: execute_batch.yml
loop:
- "{{ sleep_durations | batch(2) | list }}"
#####################
# execute_batch.yml
#####################
- name: Async sleeping for batched_items
command: sleep {{ async_item }}
async: 45
poll: 0
loop: "{{ durations }}"
loop_control:
loop_var: "async_item"
register: async_results
- name: Check sync status
async_status:
jid: "{{ async_result_item.ansible_job_id }}"
loop: "{{ async_results.results }}"
loop_control:
loop_var: "async_result_item"
register: async_poll_results
until: async_poll_results.finished
retries: 30
См. также
- Работа с плейбуками
- Введение в плейбуки
- Список рассылки пользователей
- У вас есть вопрос? Обратитесь в группу Google!
- irc.freenode.net
- IRC-чат-канал #ansible
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.5/user_guide/playbooks_async.html