Supervisor: Vị "Giám Thị" Thét Ra Lửa Đằng Sau Mọi Hệ Thống Background Job
Chào anh em! Trong các dự án Backend thực tế, việc đưa các tác vụ nặng (gửi email, tính toán báo cáo, đồng bộ dữ liệu giao dịch) vào Background Jobs (chạy ngầm) là chuyện cơm bữa.
Dù bạn đang gõ php artisan queue:work của Laravel, hay chạy một file binary worker viết bằng Go, thì thao tác quen thuộc nhất của anh em Dev khi test trên server là: Mở tmux hoặc screen lên, gõ lệnh chạy, rồi ẩn màn hình đi và rung đùi đi ngủ.
Sáng hôm sau tỉnh dậy, hệ thống báo kẹt hàng ngàn giao dịch nạp tiền. Log kiểm tra thì thấy tối qua Database bị giật lag một giây, cái tiến trình Worker báo lỗi Exception rồi... chết cứng luôn từ đêm qua.
Đó là lúc chúng ta nhận ra sự ngây thơ của mình, và cũng là lúc Supervisor phải xuất tướng.
1. Supervisor là gì?
Nói một cách dân dã, Supervisor giống như một ông Giám thị vô cùng khắc nghiệt trên hệ điều hành Linux (UNIX-like).
Nhiệm vụ duy nhất của ông giám thị này là: Nhìn chằm chằm vào các tiến trình (process) mà bạn giao phó. Nếu thấy thằng nào chết (crash), ngay lập tức tát nó dậy bắt làm việc tiếp.
Nó là một hệ thống Client/Server cho phép người dùng giám sát và điều khiển một loạt các tiến trình trên UNIX. Thay vì bạn phải tự viết các đoạn shell script while(true) lằng nhằng và hay lỗi để giữ chương trình chạy, Supervisor gom tất cả lại vào một file cấu hình duy nhất.
2. 3 "Phép Thuật" Biến Supervisor Thành Tiêu Chuẩn Của Mọi Server
Phép thuật 1: Auto-Restart (Bảo hiểm nhân thọ cho Worker)
Đây chính là mảnh ghép hoàn hảo cho triết lý "Die-to-redeliver" mà chúng ta từng bàn. Khi một worker xử lý vé qua cổng (Gate) gặp lỗi dữ liệu và quyết định exit(1) để giải phóng RAM, Supervisor sẽ phát hiện ra sự sập nguồn này trong vòng vài mili-giây.
Nhờ cờ autorestart=true trong file cấu hình, Supervisor sẽ tự động khởi động lại một tiến trình worker mới tinh, sạch sẽ, để tiếp tục hứng luồng dữ liệu tiếp theo. Hệ thống của bạn đạt đến cảnh giới "Tự phục hồi" (Self-healing) mà không cần con người can thiệp.
Phép thuật 2: Phân thân chi thuật (Process Scaling)
Vào giờ cao điểm, lượng event đổ về Message Broker tăng gấp 10 lần. Một worker chạy không xuể. Bạn muốn bật 5 worker lên chạy song song?
Thay vì phải gõ lệnh chạy 5 lần, với Supervisor, bạn chỉ cần thêm đúng một dòng vào file cấu hình:
numprocs=5
Boom! Supervisor sẽ tự động nhân bản (spawn) ra 5 tiến trình giống hệt nhau, phân bổ tải mượt mà. Khi cần scale down, chỉ việc sửa số 5 thành số 2 và gõ lệnh reload.
Phép thuật 3: Gom bi Log (Stdout/Stderr Redirection)
Khi có 5 tiến trình chạy ngầm song song, việc đọc log bằng lệnh tail thông thường sẽ biến thành ác mộng vì log bị xé vụn. Supervisor hỗ trợ gom toàn bộ stdout (log bình thường) và stderr (log báo lỗi) của cả 5 tiến trình này ném vào chung một file duy nhất, tự động xoay vòng log (log rotation) để không làm đầy ổ cứng.
3. Cấu hình "Chuẩn Thực Chiến" (Ví dụ với Laravel)
Để anh em dễ hình dung, đây là một file cấu hình chuẩn mực (/etc/supervisor/conf.d/afc-worker.conf) mà tôi hay dùng cho các luồng xử lý giao dịch cường độ cao
[program:afc-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
user=www-data
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/worker.log
stopwaitsecs=3600
Kinh nghiệm "đổ máu" từ đoạn cấu hình này:
- Tuyệt đối không chạy bằng Root: Luôn set
user=www-data(hoặc user sở hữu source code). Nếu để Supervisor chạy bằng root, nó sẽ sinh ra các file cache/log với quyền root, lát sau web server (Nginx/PHP-FPM) không ghi đè vào được sẽ văng lỗi HTTP 500 trắng trang. - Tham số sinh tử
stopwaitsecs: Khi bạn gõ lệnh restart hoặc cập nhật code mới, Supervisor sẽ gửi tín hiệuSIGTERMđể yêu cầu worker dừng lại. Nếu worker đang xử lý dở một giao dịch nạp tiền mà bị "giết" ngang thì toang. Tham sốstopwaitsecs=3600bảo Supervisor hãy kiên nhẫn chờ tối đa 1 tiếng để worker hoàn thành nốt công việc đang dở tay, cấu hình này sẽ cứu bạn khỏi vô số ca vỡ dữ liệu.
4. 3 Lệnh Thần Thánh Cần Khắc Cốt Ghi Tâm
Làm việc với Supervisor, bạn chỉ cần nhớ chuỗi combo này mỗi khi sửa file cấu hình:
supervisorctl reread: Đọc lại các file cấu hình xem có gì mới không (chưa áp dụng ngay).supervisorctl update: Bắt đầu áp dụng cấu hình mới (tự động bật thêm/tắt bớt process nếu có sự thay đổi).supervisorctl restart all: Khởi động lại toàn bộ (Dùng mỗi khi deploy code mới lên server).
Lời kết
Supervisor không phải là công nghệ gì quá mới mẻ hay hào nhoáng. Nhưng trong thế giới Backend, nơi sự ổn định (Stability) được đặt lên hàng đầu, thì một công cụ lầm lì, nhẹ bén và "nói ít làm nhiều" như Supervisor lại là thứ không thể thiếu.
Hãy từ bỏ thói quen chạy tiến trình ngầm bằng screen hay dấu & ở cuối lệnh đi. Hãy dùng Supervisor để có những giấc ngủ ngon vào ban đêm!
All rights reserved