Site logo
Tác giả
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Ngày xuất bản
Ngày xuất bản

Ansible Handlers và Notifications Part 2

Anti-Patterns Cần Tránh

❌ Anti-pattern 1: Handlers Với Side Effects Phức Tạp

# KHÔNG TỐT
handlers:
  - name: restart everything
    shell: |
      systemctl restart mysql
      systemctl restart php-fpm
      systemctl restart nginx
      redis-cli FLUSHALL
      rm -rf /tmp/*

Vấn đề: Khó debug, không idempotent, không thể selective run.

✅ Tốt hơn:

handlers:
  - name: restart mysql
    service: name=mysql state=restarted
  
  - name: restart php-fpm
    service: name=php-fpm state=restarted
  
  - name: restart nginx
    service: name=nginx state=restarted

❌ Anti-pattern 2: Handlers Phụ Thuộc Vào Biến Task

tasks:
  - name: Update config
    template:
      src: app.conf.j2
      dest: /etc/app/app.conf
    register: config_result
    notify: restart app

handlers:
  - name: restart app
    service:
      name: myapp
      state: restarted
    when: config_result.changed  # KHÔNG HOẠT ĐỘNG!

Vấn đề: Handler không thấy config_result.


Best Practices

1. Đặt Tên Handler Rõ Ràng

✅ restart nginx, reload apache, flush redis cache
❌ handler1, do stuff, fix things

2. Một Handler Một Nhiệm Vụ

Mỗi handler chỉ nên làm một việc duy nhất.

3. Sử Dụng Listen Cho Handler Groups

handlers:
  - name: stop app
    service: name=myapp state=stopped
    listen: "deploy app"
  
  - name: run migrations
    command: /opt/app/migrate.sh
    listen: "deploy app"
  
  - name: start app
    service: name=myapp state=started
    listen: "deploy app"

4. Document Dependencies

Thêm comments cho handlers có dependency:

handlers:
  # Must run before "start app"
  - name: update database schema
    command: /opt/app/migrate.sh
  
  # Depends on "update database schema"
  - name: start app
    service: name=myapp state=started

5. Test Handlers Riêng Biệt

# test-handlers.yml
---
- name: Test handlers
  hosts: localhost
  tasks:
    - name: Trigger all handlers
      command: /bin/true
      changed_when: true
      notify:
        - restart nginx
        - restart mysql
        - restart app
  
  handlers:
    # Import handlers từ role
    - import_tasks: roles/webserver/handlers/main.yml

Tổng Kết

Trong bài học này, bạn đã học:

  • ✅ Cách handlers thực sự hoạt động
  • ✅ Quản lý thứ tự thực thi handlers
  • ✅ Sử dụng listen để group handlers
  • ✅ meta: flush_handlers để chạy handlers ngay lập tức
  • ✅ Handlers trong roles
  • ✅ Graceful restart patterns
  • ✅ Best practices và anti-patterns

Bài Tập Thực Hành

Bài 1: Tạo role database với handlers để:

  • Stop MySQL
  • Backup database
  • Update configuration
  • Start MySQL
  • Verify database is running

Bài 2: Tạo playbook zero-downtime deployment với:

  • Remove server from load balancer
  • Deploy new code
  • Restart application
  • Health check
  • Add back to load balancer

Bài 3: Implement blue-green deployment pattern sử dụng handlers.

Resources