handlers 介绍

Posted jameslove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了handlers 介绍相关的知识,希望对你有一定的参考价值。

介绍playbook时提到handlers是任务处理器,和前面使用到的task一样都是用来定义任务,区别在于handlers需要满足某些条件时才会触发任务操作,所以需要一个任务通知者notify对应的handler后,任务才会被执行。不管有多少个通知者notify了handler,都需要等到playbook中所有task执行完成后,最后才执行对应的handlers,而且只会被执行一次。

开篇的描述理解起来可能会比较绕,本节会通过案例来了解handlers的具体作用。

1 问题回顾

在上一节《 playbook基础》 【2.1.5 案例4:修改配置文件】中我们预留了一个问题,现在来看下当时定义的playbook

sandboxMP) [[email protected] ~]$ cat tasks/modify_nginx.yml 
---
- hosts: server
  remote_user: root
  tasks: 
   - name: Modify the default port
     lineinfile:        
    path: /etc/nginx/nginx.conf  
     regexp: "(.*)listen(.*) 80 (.*)"     
     line: ‘\1listen\2 8080 \3‘      
     backrefs: yes
     state: present
   - name: restart nginx      
     service: name=nginx state=restarted 

  

我们的初衷想在修改配置文件后,重启对应的服务来让修改后的配置生效。在测试执行的时候确实也是实现了这个功能。

接下来再次执行这个playbook看看效果:

(sandboxMP) [[email protected] ~]$ ansible-playbook tasks/modify_nginx.yml

 

PLAY [server] ***************************************************************************************************************************************************************************************

 

TASK [Gathering Facts] ******************************************************************************************************************************************************************************

ok: [172.16.3.101]

ok: [172.16.3.102]

 

TASK [Modify the default port] **********************************************************************************************************************************************************************

ok: [172.16.3.101]

ok: [172.16.3.102]

 

TASK [restart nginx] ********************************************************************************************************************************************************************************

changed: [172.16.3.101]

changed: [172.16.3.102]

 

PLAY RECAP ******************************************************************************************************************************************************************************************

172.16.3.101               : ok=3    changed=1    unreachable=0    failed=0   

172.16.3.102               : ok=3    changed=1    unreachable=0    failed=0   

 来看下执行记录:

  • [Modify the default port]:因为在上一次运行时,已经完成了配置文件内容的修改,所以再次运行时状态时ok的,这个任务没有在远程服务器上做任何修改;
  • [restart nginx]:虽然这次没有修改配置文件内容,但是还是执行了重启nginx服务的任务,状态为changed

2 使用Handler

2.1 使用handler解决遗留问题

使用Handler就可以很好的避免上面的问题,因为Handler需要满足某些条件时才会触发任务操作。handler的使用也很简单,只需要在tasknotify对应的handler即可。修改/tmp/modify_nginx.yml,使用handlers

 

sandboxMP) [[email protected] ~]$ vim tasks/modify_nginx.yml
---
- hosts: server
  remote_user: root
  tasks: 
    - name: Modify the default port
      lineinfile:  
        path: /etc/nginx/nginx.conf     
        regexp: "(.*)listen(.*) 80 (.*)"  
        line: ‘\1listen\2 8080 \3‘        
        backrefs: yes        
        state: present      
      notify: restart nginx service # 需要执行的handler的name  
  handlers:  
    - name: restart nginx service   # 在handler中定义的一个任务
      service: name=nginx state=restarted

可以看到handler的定义和task的定义是一样的,定义handler的名称,使用的模块,以及给模块传递的参数;在task中只需要motify想要运行的handlser名称即可。注意缩进(在介绍YAML语法时,已经说明不可用Table,还是有朋友用Table来缩进,导致错误。)

运行playbook

(

sandboxMP) [[email protected] ~]# ansible-playbook tasks/modify_nginx.yml   

 

PLAY [server] ***************************************************************************************************************************************************************************************

 

TASK [Gathering Facts] ******************************************************************************************************************************************************************************

ok: [172.16.3.102]

ok: [172.16.3.101]

 

TASK [Modify the default port] **********************************************************************************************************************************************************************

ok: [172.16.3.101]

ok: [172.16.3.102]

 

PLAY RECAP ******************************************************************************************************************************************************************************************

172.16.3.101               : ok=2    changed=0    unreachable=0    failed=0   

172.16.3.102               : ok=2    changed=0    unreachable=0    failed=0   

  

可以看到 [Modify the default port] 执行结果是OK,没有发生变化操作,所以handler没有被执行(结果中没有handler的执行信息)

登陆server01(172.16.3.101),修改/etc/nginx/nginx.conf的配置,将监听端口改为80

[[email protected] ~]$ vim /etc/nginx/nginx.conf

# 找到server标签,将listen的端口改为80,保存退出‘‘‘前面内容省略‘‘‘

 server {

        listen       80 default_server;

        listen       [::]:80 default_server;

        server_name  _;

        root         /usr/share/nginx/html;

  

 

[[email protected] ~]$ systemctl restart nginx # 重启nginx服务

回到sandboxMP(172.16.3.100)重新运行playbook

(sandboxMP) [[email protected] ~]$ ansible-playbook tasks/modify_nginx.yml

 

PLAY [server] ***************************************************************************************************************************************************************************************

 

TASK [Gathering Facts] ******************************************************************************************************************************************************************************

ok: [172.16.3.102]

ok: [172.16.3.101]

 

TASK [Modify the default port] **********************************************************************************************************************************************************************

changed: [172.16.3.101]

ok: [172.16.3.102]

 

RUNNING HANDLER [restart nginx service] *************************************************************************************************************************************************************

changed: [172.16.3.101]

 

PLAY RECAP ******************************************************************************************************************************************************************************************

172.16.3.101               : ok=3    changed=2    unreachable=0    failed=0   

172.16.3.102               : ok=2    changed=0    unreachable=0    failed=0

  

运行结果说明:

  • [Modify the default port]server01的配置内容被任务修改了(80变为8080),状态是changed;而 servier028080,没有被任务修改,状态是ok
  • [restart nginx service]:因为server01(172.16.3.101)文件发生了变化,所以通过notify成功执行了handler,重启了nginx服务;servier02(172.16.3.102)没有执行handler

所以当需要批量修改配置文件,需要重启服务时,合理的使用handlers,可以有效的避免不必要的重启操作。

2.1 创建多个handlers

tasks一样也可以创建多个handlers,一个task可以notify多个handlers,多个task也可以notify同一个handler,例如:

# 以下实例只用于说明,不需要在系统上进行测试(系统上没有这些环境)

---

- hosts: server
remote_user: root tasks:
- name: upload project files copy: src: /root/project dest: /tmp/ notify: - restart nginx service
- restart mysql service
handlers: - name: restart nginx service
service: name=nginx state=restarted - name: restart mysql service
service: name=mysql state=restarted

  

在上面的演示的playbook中假设上传了一个项目文件,然后重启nginxmysql服务。

 

以上是关于handlers 介绍的主要内容,如果未能解决你的问题,请参考以下文章

自定义无内存泄漏的Handler内部类

什么时候可以在android中使用强引用,这个代码是否泄漏?

Android SwipeRefreshLayout 官方下拉刷新控件介绍—Handler原理—Adapter总结

handlers 介绍

Android课程---Android Studio使用小技巧:提取方法代码片段

不频繁的 Handler.post 导致大量丢帧和崩溃