ansible同步模式与异步模式

时间:2023-02-14 12:16:05

一、概述

1、同步模式:
如果节点数太多,ansible无法一次在所有远程节点上执行任务,那么将先在一部分节点上执行一个任务(每一批节点的数量取决于fork进程
数量,默认为5个,可设置),直到这一批所有节点上该任务完全执行完毕才会接入下一个批节点,直到所有节点将该任务都执行完毕,然后重
新回到第一批节点开始执行第二个任务。依次类推,直到所有节点执行完所有任务,ansible端才会释放shell。这是默认同步模式,也就是
说在未执行完毕时,ansible是占用当前shell的,任务执行完后,释放shell了才可以输入其他命令做其他动作。

2、异步模式:
假如fork控制的并发进程数为5,远程控制节点为24个,则ansible一开始会将5个节点的任务扔在后台,并每隔一段时间去检查这些节点的任
务完成情况,当某节点完成不会立即返回,而是继续等待直到5个进程都空闲了,才会将这5个节点的结果返回给ansible端,ansible会继续
将下一批5个节点的任务扔在后台并每隔一段时间进行检查,依次类推,直到完成所有任务。
在异步模式下,如果设置的检查时间间隔为0,在将每一批节点的任务丢到后台后都会立即返回ansible,并立即将下一批节点的任务丢到后台
,直到所有任务都丢到后台完后,才返回ansible端,ansible才会立即释放占用的shell。
即此时ansible是不会管各个节点任务执行情况的,不管执行成功或失败。因此在轮训检查时间内,ansible仍然正在运行(尽管某批任务已经
被放到后台执行了),当前shell进程仍被占用处于睡眠状态,只有指定的检查时间间隔为0,才会尽快将所有任务放到后台并释放shell。

3、默认情况
Anisble默认是同步阻塞模式,他会等待所以机器执行完毕后才会向前台返回。Ansible默认只会创建5个进程执行并发任务。
Anisble除了支持同步模式外还支持异步模式。下面的这种情况需要使用的异步特性
(1)当我们有一个task需要运行很长的时间,而且这个task可能会达到timeout时。
(2)当我们有一个任务需要在大量的机器上运行时
(3)当我们有一个任务不需要等待它完成时
Ansible有时候要执行等待时间很长的操作,这个操作可能要持续很长时间,设置超过ssh的timeout。这种情况下可以选择在step中指定
async和poll来实现异步操作。其中:
async:表示这个step的最长等待时长, 如果设置为0, 表示一直等待下去直到动作完成;
poll:表示检查step操作结果的间隔时长。如果poll为0,就相当于一个不关心结果的任务。

4、官方给的示例代码如下所示:
复制代码
---
- 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:代表这个任务执行时间的上线值,如果执行所用时间超过了这个时间点,则认为任务失败,若没设置参数,则同步执行
poll:表示 任务异步执行时间轮询的时间间隔
在此异步模式下,Ansible 会将节点的任务丢在后台,每台被控制的机器都有一个job_id, Ansible 会根据这个job id去轮询该机器上任务
的执行情况,例如某机器H此任务中的某一个阶段是否完成,是否进入下一个阶段等。即使任务早就结束了,也只有等轮询检查到任务结束之
后才认为该任务结束。可以指定任务检查的时间间隔,默认是10秒。除非指定任务检查的时间间隔为0,否则会等待所有任务都完成后,
Ansible 端才会释放占用的Shell.如果指定的时间间隔为0,则Ansible会立即返回(至少得连接上目标主机,任务发布成功之后立即返回),
并且不会检查它的任务进度。

ansible webserver -B 30 P 0 -m yum -a ' name=php' -vv
参数说明:-B 30 表示启用异步,超时时间为30秒,-P0表示轮询时间为0 既不检查任务进度,立即返回结果

二、命令行中的设置

1、配置文件默认
/etc/ansible/ansible.cfg中默认:
#poll_interval = 15

2、命令行参数
ansible --help
#async:表示这个step的最长等待时长, 如果设置为0, 表示一直等待下去直到动作完成;
-B SECONDS, --background=SECONDS
run asynchronously, failing after X seconds
(default=N/A)
#poll:表示检查step操作结果的间隔时长。
-P POLL_INTERVAL, --poll=POLL_INTERVAL
set the poll interval if using -B (default=15) #默认值是读取的/etc/ansible/ansible.cfg配置文件

3、命令行基础测试
只要使用了async,不管执行成功还是失败,数据结果返回时间都会大于poll值
异步实际返回结果时间是远远大于运行时间的
3.1、只设置async参数,失败现象
time ansible 192.168.10.131 -B 10 -m shell -a "sleep 60 ;echo 111" -i hosts
192.168.10.131 | FAILED | rc=-1 >> #超时直接报错退出,不指定poll默认使用配置文件里面的#poll_interval = 15
async task did not complete within the requested time
real 0m17.381s #real是实际命令运行结束时时钟时间差,包括进程运行、阻塞等时间,
user 0m2.180s #user 时间都是运行的时间,用户态代码运行(不包含阻塞) ,
sys 0m0.338s #sys是系统态代码运行时间
3.2、只设置async参数,成功现象
time ansible 192.168.10.131 -B 10 -m shell -a "echo 111" -i hosts
192.168.10.131 | CHANGED | rc=0 >>
111
real 0m18.257s
user 0m2.088s
sys 0m0.289s
3.3、正常情况
time ansible 192.168.10.131 -B 10 -P 10 -m shell -a "echo 111" -i hosts
192.168.10.131 | CHANGED | rc=0 >>
111
real 0m14.308s
user 0m1.847s
sys 0m0.315s

4、async为0
async 表示这个step的最长等待时长, 如果设置为0, 表示一直等待下去直到动作完成.
相当于同步情况,poll设置失效
time ansible 192.168.10.131 -B 0 -P 80 -m shell -a "sleep 20;echo 111" -i hosts
7.225.23.227 | CHANGED | rc=0 >>
111
real 0m23.968s
user 0m2.918s
sys 0m0.346s

5、poll为0
poll 设置为0, 表示不用等待执行结果, 该step执行成功
time ansible 192.168.10.131 -B 10 -P 0 -m shell -a "sleep 20;echo 111" -i hosts
7.225.23.227 | CHANGED | rc=-1 >> #但是此处rc=-1应该是失败才对

real 0m3.596s
user 0m1.201s
sys 0m0.126s

三、yaml中设置

1、超时中断
- hosts : test_server
tasks :
- name : ansible-test
shell : sleep 10
#async表示上述shell命令的等待时间,设置为0时会一直等待命令结束
async : 5
#poll表示检查step操作结果的间隔时长,设置为0表示 不用等待结果,继续做下面的操作,我们可以在下面的step中来验证这个命令是否成功执行.
poll : 2
这个step失败, 因为ansible的任务(就是上面配置中的shell动作)操作时间(10s)超过了最大等待时长(5s)

2、poll设置为0
poll 设置为0, 表示不用等待执行结果, 该step执行成功
---
- name: Test
hosts: localhost
tasks:
- name: wair for
shell: sleep 16
async: 10
poll: 0

3、async设置为0
async设置为0, 会一直等待直到该操作完成.
---
- name: Test
hosts: localhost
tasks:
- name: wair for
shell: sleep 16
async: 0
poll: 10