Series Dockerize Laravel Thực chiến #4: Giải phóng Nginx – Tích hợp Redis & "Nhà máy" Queue Worker
1. Gọi Redis vào đội hình Docker Compose
Redis là lựa chọn hoàn hảo và tốc độ nhất để quản lý Queue trong Laravel. Đầu tiên, chúng ta cần bổ sung một container chạy Redis vào hệ sinh thái.
Bạn hãy mở file docker-compose.yml (đã viết ở Bài 2) và nạp thêm service redis vào bên dưới service db:
# ... (các service webserver, app, db giữ nguyên) ...
# 4. Container Redis (Cache & Queue)
redis:
image: redis:7.0-alpine
container_name: laravel_redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data # Khai báo volume để dữ liệu không mất khi tắt
networks:
- laravel_network
# Đừng quên thêm volume mới ở dưới cùng file
volumes:
db_data:
redis_data:
2. Thiết lập "Nhà máy" Queue Worker bằng kỹ thuật Nhân bản
Đây là điểm cực kỳ thú vị của kiến trúc Docker. Để chạy Queue Worker trong Laravel, lệnh thường dùng là php artisan queue:work.
Nếu chạy thủ công lệnh này bằng cách docker-compose exec app..., tiến trình sẽ bị chết ngay khi bạn tắt Terminal. Chúng ta cần một container chạy ngầm 24/7. Nhưng khoan! Chúng ta không cần phải viết một Dockerfile mới. Queue Worker thực chất vẫn cần mã nguồn PHP, cần thư viện y hệt như container app.
Tuyệt kỹ ở đây là: Sử dụng lại chung một cấu hình build với app, nhưng ghi đè lệnh khởi động (command).
Hãy thêm tiếp khối code này vào docker-compose.yml:
# 5. Container Queue Worker (Công nhân chạy ngầm)
queue-worker:
build:
context: .
dockerfile: docker/php/Dockerfile
container_name: laravel_queue_worker
restart: unless-stopped
volumes:
- ./:/var/www/html
# Ghi đè lệnh mặc định của PHP-FPM thành lệnh chạy Worker
command: php artisan queue:work redis --sleep=3 --tries=3 --timeout=90
depends_on:
- redis
- db
networks:
- laravel_network
Với định nghĩa này, container queue-worker sẽ dùng chung mã nguồn và môi trường với Nginx/PHP, nhưng thay vì ngồi đợi HTTP request, nó sẽ liên tục "hút" các Job từ Redis ra để xử lý âm thầm.
3. Cấu hình Laravel để kết nối với Redis
Kiến trúc hạ tầng đã xong, bây giờ chúng ta cần bảo Laravel biết cách nói chuyện với con Redis mới được dựng lên.
Bước 1: Cài đặt thư viện giao tiếp Redis
Sử dụng công cụ Alias từ Bài 3 để cài gói predis:
d-composer require predis/predis
Bước 2: Cập nhật biến môi trường
Bạn mở file .env của Laravel và sửa lại các cấu hình kết nối. Hãy nhớ, chúng ta không dùng 127.0.0.1, mà dùng tên của container (redis và db) để các container tự tìm thấy nhau trong mạng ảo:
# Đổi kết nối DB sang tên container mysql
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
# Bật Redis làm driver cho Cache và Queue
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
# Cấu hình IP trỏ vào container redis
REDIS_CLIENT=predis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
4. Khởi động và Giám sát hệ thống ngầm
Giờ đây, trận đồ của bạn đã trở nên rất bề thế với 5 container: Web, PHP, DB, Redis, và Queue Worker. Hãy khởi động lại toàn bộ để Docker nạp cấu hình mới:
docker-compose up -d
Để chắc chắn "công nhân" Queue Worker đang chăm chỉ làm việc ở chế độ ngầm mà không bị văng lỗi, bạn có thể kiểm tra log trực tiếp của riêng container đó:
docker logs -f laravel_queue_worker
Nếu Terminal hiển thị sự im lặng, hoặc thỉnh thoảng hiện lên dòng Processing... và Processed..., xin chúc mừng! Hệ thống hàng đợi của bạn đã đi vào hoạt động trơn tru.
Tổng kết
Bằng việc tách rời luồng xử lý HTTP (Nginx + PHP-FPM) và luồng xử lý nền (Queue Worker qua Redis), ứng dụng Laravel của bạn hiện đã đạt tiêu chuẩn về kiến trúc Micro-service cơ bản. Các tác vụ nặng như tạo file báo cáo, đồng bộ dữ liệu giao dịch vé, hay gửi hàng loạt email chiến dịch giờ đây sẽ được ném thẳng vào hàng đợi. Người dùng sẽ luôn nhận được phản hồi ngay tức khắc, trong khi các container Worker âm thầm giải quyết khối lượng công việc khổng lồ ở phía sau.
Đây chính là tư duy thiết kế cốt lõi giúp các hệ thống lớn luôn giữ được độ mượt mà dưới áp lực tải cao.
All rights reserved