Nginx config sai gây lỗi 502 lúc đông traffic: Nguyên nhân phổ biến và cách xử lý chuẩn

Lỗi 502 Bad Gateway lúc ít người truy cập thì không thấy, nhưng cứ hễ đông traffic là website “đột tử” — đây là kiểu đau khổ rất quen với Nginx + PHP-FPM. Tin vui: đa số case không phải do “server yếu”, mà do cấu hình Nginx/PHP-FPM sai hoặc thiếu giới hạn hợp lý. Bài này sẽ chỉ ra các nguyên nhân hay gặp nhất khiến 502 bùng lên khi tải cao, cách kiểm tra nhanh, và cấu hình gợi ý để website ổn định hơn.

Nginx config sai gây lỗi 502 lúc đông traffic: Nguyên nhân phổ biến và cách xử lý chuẩ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


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...