- 502 lúc đông traffic là gì (hiểu đúng để sửa đúng)
- Dấu hiệu “chuẩn bài” của 502 do cấu hình sai
- Bước 1: Nhìn log để khỏi đoán mò
- Nguyên nhân 1: PHP-FPM bị nghẽn vì pm.max_children quá thấp
- Nguyên nhân 2: Nginx timeout quá thấp hoặc không đồng bộ với PHP-FPM
- Nguyên nhân 3: Dùng TCP upstream (127.0.0.1:9000) mà backlog/conn bị “kẹt”
- Nguyên nhân 4: Buffer sai khiến upstream trả về “quá to” rồi Nginx choke
- Nguyên nhân 5: Worker/connection của Nginx quá thấp (nghẽn ở cửa)
- Nguyên nhân 6: Keepalive cấu hình sai khiến server giữ quá nhiều kết nối rảnh
- Nguyên nhân 7: Không giới hạn request gây “bão” (throttle/limit) nên backend chết trước
- Nguyên nhân 8: MySQL chậm làm PHP treo, Nginx tưởng upstream “chết”
- Checklist cấu hình tối thiểu để giảm 502 khi traffic tăng
- Mẫu block PHP location gọn, ổn định cho đa số website
- Kết luận: 502 lúc đông traffic thường là “nghẽn” chứ không phải “hết tài nguyên”
502 lúc đông traffic là gì (hiểu đúng để sửa đúng)
Trong mô hình phổ biến, Nginx là reverse proxy nhận request, rồi chuyển qua PHP-FPM (hoặc upstream khác) để xử lý. 502 nghĩa là Nginx không nhận được phản hồi hợp lệ từ upstream (PHP-FPM chết, quá tải, timeout, hoặc trả về dữ liệu lỗi).
Dấu hiệu “chuẩn bài” của 502 do cấu hình sai
Thường gặp các biểu hiện:
- Lúc bình thường chạy ổn, peak traffic là 502 hàng loạt.
- Refresh vài lần lại vào được (không chết hẳn).
- CPU/RAM chưa chắc full, nhưng queue và process upstream bị nghẽn.
- Error log Nginx có các dòng kiểu timeout, connect failed, upstream prematurely closed connection.
Bước 1: Nhìn log để khỏi đoán mò
Đừng “tối ưu bằng niềm tin”. Hãy xem log trước:
tail -n 200 /var/log/nginx/error.log
tail -n 200 /var/log/php8.3-fpm.log
tail -n 200 /var/log/php8.3-fpm/www-error.log
Các cụm từ bạn cần để ý trong Nginx error log:
upstream timed out(PHP xử lý quá lâu hoặc FPM nghẽn)connect() failed (111: Connection refused)(FPM chết hoặc không accept kịp)no live upstreams(upstream down)upstream prematurely closed connection(FPM crash/kill, memory limit, hoặc backend đóng sớm)
Nguyên nhân 1: PHP-FPM bị nghẽn vì pm.max_children quá thấp
Triệu chứng: traffic tăng là 502, log có timeout, hoặc Nginx chờ hoài upstream.
Vì sao: mỗi request PHP cần 1 worker FPM. Khi hết worker, request sẽ xếp hàng. Nếu hàng chờ dài hơn timeout của Nginx, 502 xảy ra.
Cách kiểm tra: bật status của FPM (nếu có) hoặc xem log FPM. Ngoài ra xem số process:
ps -ylC php-fpm8.3 --sort:rss
systemctl status php8.3-fpm
Cách sửa: chỉnh pool config (ví dụ /etc/php/8.3/fpm/pool.d/www.conf) theo RAM thực tế. Gợi ý kiểu an toàn:
pm = dynamic
pm.max_children = 30
pm.start_servers = 6
pm.min_spare_servers = 6
pm.max_spare_servers = 12
pm.max_requests = 500
Chọn pm.max_children như thế nào: lấy RAM khả dụng cho PHP chia cho RAM trung bình mỗi process PHP-FPM. Ví dụ mỗi process ~60MB, bạn dành 2GB cho PHP thì tối đa khoảng 2000/60 ≈ 33. Làm tròn xuống để chừa RAM cho MySQL/Redis/system.
Nguyên nhân 2: Nginx timeout quá thấp hoặc không đồng bộ với PHP-FPM
Triệu chứng: request nặng (admin, search, cache miss) dễ 502 khi traffic tăng.
Vì sao: Nginx chờ upstream không đủ lâu: fastcgi_read_timeout thấp, hoặc backend xử lý lâu vì queue.
Cách sửa: set timeout hợp lý (đừng quá cao nếu sợ treo worker), và tối ưu truy vấn/IO để request không kéo dài vô tận.
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_connect_timeout 10s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
}
Nếu site có tác vụ nặng (import, report), bạn có thể tách riêng location cho admin hoặc endpoint cụ thể, không nên nâng timeout toàn site bừa bãi.
Nguyên nhân 3: Dùng TCP upstream (127.0.0.1:9000) mà backlog/conn bị “kẹt”
Triệu chứng: cao tải là connect failed, connection refused, intermittent 502.
Vì sao: TCP có thêm overhead và phụ thuộc backlog/socket queue. Khi peak, việc accept kết nối có thể nghẽn.
Cách sửa: nếu cùng máy, ưu tiên unix socket (nhẹ và ổn định hơn):
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
Và đảm bảo quyền socket đúng user/group Nginx.
Nguyên nhân 4: Buffer sai khiến upstream trả về “quá to” rồi Nginx choke
Triệu chứng: hay xảy ra với response lớn (admin, HTML dài, headers/cookie to), log có liên quan đến buffer.
Cách sửa: tăng buffer vừa đủ, không phang bừa:
fastcgi_buffer_size 32k;
fastcgi_buffers 16 32k;
fastcgi_busy_buffers_size 64k;
Nếu dùng WordPress, cookie đôi khi rất dài (nhất là nhiều plugin). Làm UI gọn lại, giảm cookie cũng là cách “cứu” backend.
Nguyên nhân 5: Worker/connection của Nginx quá thấp (nghẽn ở cửa)
Triệu chứng: không chỉ PHP, mà cả request tĩnh cũng chậm; Nginx “không đủ tay” để phục vụ đồng thời.
Cách sửa cơ bản:
worker_processes auto;
events {
worker_connections 4096;
multi_accept on;
}
Và nhớ kiểm tra giới hạn file descriptor:
ulimit -n
Nếu ulimit thấp mà worker_connections cao, bạn vẫn nghẽn như thường.
Nguyên nhân 6: Keepalive cấu hình sai khiến server giữ quá nhiều kết nối rảnh
Triệu chứng: lúc đông traffic, nhiều connection “treo”, RAM/FD tăng, 502 xuất hiện.
Cách sửa: keepalive vừa đủ, đừng để quá lâu:
keepalive_timeout 15;
keepalive_requests 1000;
Nguyên nhân 7: Không giới hạn request gây “bão” (throttle/limit) nên backend chết trước
Triệu chứng: gặp bot, crawl mạnh, hoặc spam endpoint (search, xmlrpc, wp-login) là 502/504.
Cách sửa: limit theo IP cho các endpoint nhạy cảm:
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s;
server {
location = /wp-login.php {
limit_req zone=req_zone burst=20 nodelay;
}
location = /xmlrpc.php {
deny all;
}
}
Chốt câu: đừng để PHP-FPM phải “đỡ đạn” thay Nginx.
Nguyên nhân 8: MySQL chậm làm PHP treo, Nginx tưởng upstream “chết”
Triệu chứng: 502 tăng cùng lúc với query chậm, CPU MySQL cao, disk IO cao.
Cách xử lý: bật slow query log, xem top query, tối ưu index/caching. Nginx không sai, nhưng nó là thằng bị chửi đầu tiên.
Checklist cấu hình tối thiểu để giảm 502 khi traffic tăng
Dưới đây là checklist “ít mà chất”:
- Nginx: worker_processes auto, worker_connections đủ lớn, keepalive hợp lý
- PHP-FPM: pm.max_children đúng với RAM, pm.max_requests để tránh memory leak kéo dài
- fastcgi timeout đồng bộ, không quá thấp
- Ưu tiên unix socket nếu cùng server
- limit endpoint nhạy cảm (login/search/xmlrpc)
- Cache đúng cách (full page cache nếu phù hợp), giảm request vào PHP
Mẫu block PHP location gọn, ổn định cho đa số website
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_connect_timeout 10s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
fastcgi_buffer_size 32k;
fastcgi_buffers 16 32k;
}
Kết luận: 502 lúc đông traffic thường là “nghẽn” chứ không phải “hết tài nguyên”
Nếu bạn gặp 502 theo kiểu “đông là chết, vắng là sống”, 80% là do queue/worker/timeouts không khớp giữa Nginx và PHP-FPM, hoặc bị bot đấm vào endpoint nhạy cảm. Sửa đúng điểm nghẽn, web sẽ ổn định hơn rất nhiều mà chưa cần nâng VPS.
Bình luận