Series Docker & Nginx cho Laravel #2: Nghệ thuật chống "Dội bom" và Ép xung Băng thông
1. Rate Limiting: Lá chắn chống DDoS nội bộ
Để ngăn chặn các đợt bùng nổ lưu lượng (Spike Traffic) hoặc các cuộc tấn công DDoS, Nginx cho phép chúng ta cấp phát "hạn mức" truy cập cho từng IP. Những Request vượt quá hạn mức sẽ bị Nginx thẳng tay ném ra lỗi 503 Service Unavailable ngay lập tức, hoàn toàn không chạm tới Laravel.
Mở lại file nginx/conf.d/default.conf, chúng ta sẽ khai báo một vùng nhớ (Zone) để theo dõi IP của các trạm gửi request.
Khai báo vùng nhớ ở NGOÀI block server:
# Tạo vùng nhớ tên là 'api_limit', kích thước 10MB (đủ lưu khoảng 160,000 IP)
# Tốc độ giới hạn: 10 request / giây / 1 IP
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
# ... các cấu hình cũ
Áp dụng lá chắn vào các Route API trọng yếu ở TRONG block server:
# Bảo vệ riêng khu vực API đồng bộ giao dịch
location /api/v1/sync {
# Áp dụng vùng nhớ 'api_limit'
# burst=20: Cho phép 20 request vượt rào được xếp hàng chờ (buffer) thay vì chặn ngay
# nodelay: Xử lý ngay lập tức những request trong buffer, không cố tình làm chậm
limit_req zone=api_limit burst=20 nodelay;
# Chuyển việc xuống cho PHP như bình thường
try_files $uri $uri/ /index.php?$query_string;
}
Với cấu hình này, nếu một máy trạm bị lỗi phần mềm và dội 100 request/giây lên /api/v1/sync, Nginx sẽ cho qua 10 request hợp lệ, nạp 20 request vào buffer dự phòng, và thẳng tay "chém" rụng 70 request còn lại. Laravel vẫn sống khỏe để xử lý lượng dữ liệu an toàn.
2. Ép xung băng thông với Gzip / Brotli
Khi các thiết bị AFC gửi lên (hoặc Server trả về) một mảng chứa 1000 giao dịch dưới dạng JSON, dung lượng file có thể lên tới 5MB. Việc truyền tải 5MB text thô qua mạng là một sự lãng phí băng thông khổng lồ, làm tăng độ trễ (Latency).
Nginx tích hợp sẵn module Gzip để nén dữ liệu text (HTML, CSS, JS, JSON) trước khi gửi đi, và Client sẽ tự giải nén.
Thêm đoạn sau vào block server:
# Bật tính năng nén Gzip
gzip on;
# Mức độ nén từ 1-9 (Mức 5 là tỷ lệ vàng giữa dung lượng và CPU)
gzip_comp_level 5;
# Dung lượng tối thiểu để nén (Không nén các file quá bé, gây tốn CPU vô ích)
gzip_min_length 256;
# Chỉ định đích danh các loại file cần nén (Đặc biệt là JSON của API)
gzip_types
application/json
application/javascript
application/xml
text/css
text/plain;
# Cho phép proxy cache lại bản đã nén
gzip_proxied any;
Kết quả: File JSON 5MB giờ đây chỉ còn khoảng 500KB khi chạy qua đường truyền. Trải nghiệm tốc độ API sẽ tăng lên gấp nhiều lần.
3. Mở rộng ranh giới Upload (Client Max Body Size)
Mặc định, Nginx rất bảo thủ. Nó giới hạn dung lượng của một request body (ví dụ: payload JSON gửi qua POST, hoặc file đính kèm) chỉ ở mức 1MB.
Nếu một nhà ga cố gắng đồng bộ một file Log thiết bị hoặc một cục JSON Offline nặng 5MB, Nginx sẽ ngay lập tức chặn lại và ném ra lỗi 413 Request Entity Too Large mà không thèm báo cáo cho Laravel.
Để khắc phục, bạn cần mở rộng ranh giới này một cách có chủ đích:
server {
listen 80;
server_name localhost;
# Mở rộng giới hạn body lên 50MB cho toàn bộ Server
client_max_body_size 50M;
# ...
}
Mẹo Senior: Hãy cấu hình client_max_body_size ở mức vừa đủ dùng (ví dụ 10M hoặc 50M) thay vì vô hiệu hóa nó (bằng cách set về 0). Việc không giới hạn dung lượng sẽ mở đường cho Hacker dội những payload khổng lồ làm treo RAM của server.
4. Khai phóng sức mạnh CPU (Worker Processes)
Nếu bạn mua một con Server xịn có 16 nhân (16 Cores CPU) để chạy Docker, nhưng Nginx lại chỉ chạy trên 1 nhân, thì đó là một sự lãng phí thảm họa.
Mặc dù trong môi trường Docker, file nginx.conf tổng thường đã được cấu hình khá tốt, một DevOps Senior luôn chủ động kiểm soát tiến trình (Worker). Bạn có thể ánh xạ file nginx.conf gốc vào container để tinh chỉnh:
# /etc/nginx/nginx.conf
# auto: Tự động đếm số nhân CPU thực tế của Server để bung ra số lượng worker tương ứng
worker_processes auto;
events {
# Mỗi worker có thể giữ tối đa bao nhiêu kết nối đồng thời?
# Nếu server có 4 nhân CPU -> 4 x 2048 = 8192 kết nối đồng thời.
worker_connections 2048;
# Cho phép worker nhận nhiều kết nối cùng lúc thay vì nhận từng cái một
multi_accept on;
}
Đến đây, bạn đã hoàn tất việc biến Nginx từ một "tay mở cửa" nghiệp dư thành một vị Tướng gác cổng thực thụ. Bằng Rate Limiting chặn đứng dội bom, Gzip tối ưu đường truyền và kiểm soát chặt chẽ Body Size, ứng dụng Laravel phía sau đã hoàn toàn yên tâm tập trung vào việc xử lý logic lõi.
Cùng với Redis (Cache), ELK (Log/Monitor) và Nginx (Web Server) đóng gói trong Docker, bộ khung kiến trúc Micro-service cơ bản cho hệ thống vận hành trạm của bạn đã được đúc kết hoàn chỉnh và bền vững.
All Rights Reserved