响应事件(Handler)

什么是handler?

每个主流的编程语言都会有event机制,那么handler就是playbook的event。

Handlers里面的每一个handler,也是对module的一次调用。而handlers与tasks不同,tasks会默认的按定义顺序执行每一个task,handlers则不会,它需要在tasks中被调用,才有可能被执行。

Tasks中的任务都是有状态的,changed或者ok。 在Ansible中,只在task的执行状态为changed的时候,才会执行该task调用的handler,这也是handler与普通的event机制不同的地方。

应用场景

什么情况下使用handlers呢?

如果你在tasks中修改了apache的配置文件。需要重起apache。此外还安装了apache的插件。那么还需要重起apache。像这样的应该场景中,重起apache就可以设计成一个handler.

一个handler最多只执行一次

在所有的任务里表执行之后执行,如果有多个task notify同一个handler,那么只执行一次。

在下面的例子里apache只执行一次

https://github.com/ansible-book/ansible-first-book-examples/blob/master/handlers_state.yml

---
- hosts: lb
  remote_user: root
  vars:
      random_number1: "\{\{ 10000 | random \}\}"
      random_number2: "\{\{ 10000000000 | random \}\}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number1 \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number1 \}\}
    notify:
      - call in every action
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number2 \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number2 \}\}
    notify:
      - call in every action

  handlers:
  - name: call in every action
    debug: msg="call in every action, but execute only one time"

action是Changed ,才会执行handler

只有当TASKS种的action的执行状态是changed时,才会触发notify handler的执行。

下面的脚本执行两次,执行结果是不同的:

测试代码见:

https://github.com/shijingjing1221/ansible-first-book-examples/blob/master/handlers_execution_time.yml

---
- hosts: lb
  remote_user: root
  vars:
      random_number: "\{\{ 10000 | random \}\}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts
    copy: src=/etc/hosts dest=/tmp/hosts
    notify:
      - call by /tmp/hosts
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number \}\}
    notify:
      - call by /tmp/hosts.random_number

  handlers:
  - name: call by /tmp/hosts
    debug: msg="call first time"
  - name: call by /tmp/hosts.random_number
    debug: msg="call by /tmp/hosts.random_number"

  

按Handler的定义顺序执行

handlers是按照在handlers中定义个顺序执行的,而不是安装notify的顺序执行的。

下面的例子定义的顺序是1>2>3,notify的顺序是3>2>1,实际执行顺序:1>2>3.

---
- hosts: lb
  remote_user: root
  gather_facts: no
  vars:
      random_number1: "\{\{ 10000 | random \}\}"
      random_number2: "\{\{ 10000000000 | random \}\}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number1 \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number1 \}\}
    notify:
      - define the 3nd handler
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number2 \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number2 \}\}
    notify:
      - define the 2nd handler
      - define the 1nd handler

  handlers:
  - name: define the 1nd handler
    debug: msg="define the 1nd handler"
  - name: define the 2nd handler
    debug: msg="define the 2nd handler"
  - name: define the 3nd handler
    debug: msg="define the 3nd handler"