Sửa lỗi 504 Gateway Time-out: Cách khắc phục lỗi Timeout Upstream của Nginx

intermediate🌐 Networking2026-06-15| Linux (Ubuntu/CentOS/Debian), Nginx 1.18+, PHP-FPM, Python/Gunicorn, Node.js

Error Message

504 Gateway Time-out
#nginx#gateway-timeout#mạng#proxy#php-fpm#devops

Vấn đề

Ít có điều gì gây ức chế hơn việc phải nhìn chằm chằm vào một màn hình trắng xóa trong khi trình duyệt trả về lỗi 504 Gateway Time-out. Điều này xảy ra khi Nginx đóng vai trò là một bên trung gian (proxy) và chuyển tiếp thành công yêu cầu đến backend của bạn—chẳng hạn như PHP-FPM, Gunicorn hoặc Node.js—nhưng backend đó lại mất quá nhiều thời gian để phản hồi. Về mặt kỹ thuật, Nginx mất kiên nhẫn và đóng kết nối vì phản hồi không đến trong khoảng thời gian cho phép.

Xác định nguyên nhân gốc rễ

Trước khi bắt đầu điều chỉnh các tệp cấu hình một cách mù quáng, hãy kiểm tra nhật ký lỗi (error logs) của Nginx để xác nhận dịch vụ nào đang bị đình trệ. Chạy lệnh sau để theo dõi nhật ký theo thời gian thực:

sudo tail -f /var/log/nginx/error.log

Hãy chú ý đến một dòng trông giống như thế này:

[error] 12345#0: *678 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 1.2.3.4, server: example.com, request: "GET /api/reports HTTP/1.1", upstream: "http://127.0.0.1:8000/api/reports"

Nếu bạn thấy "upstream timed out," điều đó xác nhận rằng ứng dụng đang chạy trên cổng 8000 chính là điểm nghẽn. Theo mặc định, Nginx đợi 60 giây để nhận phản hồi; nếu báo cáo hoặc cuộc gọi API của bạn mất 61 giây, nó sẽ kích hoạt lỗi 504.

Giải pháp 1: Tăng thời gian chờ (Timeout) cho Nginx Proxy

Nếu bạn sử dụng Nginx làm reverse proxy cho Node.js, Python hoặc Go, bạn cần kéo dài thời gian chờ trong khối server hoặc location. Hầu hết người dùng thấy rằng 300 giây (5 phút) là đủ cho các tác vụ xử lý nặng.

Mở tệp cấu hình trang web của bạn (thường là /etc/nginx/sites-available/default) và cập nhật các dòng sau:

location / {
    proxy_pass http://your_backend;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
    send_timeout 300s;
}
- **proxy_connect_timeout:** Thời gian Nginx chờ để thiết lập kết nối (handshake) với backend.
- **proxy_read_timeout:** Thủ phạm phổ biến nhất. Đây là thời gian Nginx chờ backend gửi lại dữ liệu sau khi kết nối đã được mở.
- **proxy_send_timeout:** Thời gian Nginx chờ để hoàn tất việc gửi yêu cầu của bạn đến backend.

Giải pháp 2: Khắc phục lỗi 504 cho PHP-FPM

Đối với các trang web WordPress hoặc Laravel, chỉ thay đổi Nginx thôi là chưa đủ. PHP-FPM có các bộ đếm thời gian nội bộ riêng sẽ dừng một tập lệnh ngay cả khi Nginx vẫn đang chờ.

1. Cập nhật cấu hình Nginx FastCGI

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    fastcgi_read_timeout 300s;
}

2. Cập nhật thiết lập PHP-FPM Pool

Chỉnh sửa cấu hình pool của bạn (ví dụ: /etc/php/8.2/fpm/pool.d/www.conf) và đặt request_terminate_timeout khớp với cài đặt Nginx của bạn:

request_terminate_timeout = 300

3. Cập nhật php.ini

Cuối cùng, hãy đảm bảo giới hạn thời gian thực thi của PHP cho phép có thêm thời gian:

max_execution_time = 300

Giải pháp 3: Khắc phục lỗi 504 cho Python (Gunicorn/Uvicorn)

Gunicorn nổi tiếng là nghiêm ngặt, với thời gian chờ mặc định chỉ 30 giây. Nếu việc xuất dữ liệu mất 35 giây, Gunicorn sẽ dừng tiến trình worker, dẫn đến việc Nginx báo lỗi 504 vì kết nối đã biến mất.

Khởi chạy Gunicorn với cờ timeout cao hơn:

gunicorn --timeout 300 myapp.wsgi:application

Các bước xác minh

Sau khi bạn đã điều chỉnh các cài đặt, hãy xác minh xem cú pháp Nginx của bạn có còn hợp lệ hay không:

sudo nginx -t

Nếu quá trình kiểm tra thành công, hãy tải lại các dịch vụ để áp dụng các giới hạn mới:

sudo systemctl reload nginx
sudo systemctl restart php8.2-fpm  # Chỉ khi bạn đang sử dụng PHP

Kiểm tra lại yêu cầu. Nếu bạn vẫn gặp lỗi 504 sau đúng 300 giây, có khả năng thời gian chờ đang xảy ra ở cấp độ cao hơn như Cloudflare hoặc AWS Load Balancer.

Phòng ngừa và Tối ưu hóa

Việc tăng thời gian chờ giúp ngăn trang lỗi xuất hiện, nhưng nó không khắc phục được một backend chậm chạp. Các yêu cầu chạy lâu sẽ chiếm dụng các tiến trình worker và cuối cùng có thể làm hỏng máy chủ của bạn khi có lưu lượng truy cập lớn.

- **Optimize Database Queries:** Việc thiếu chỉ mục (index) trên một bảng có 500.000 hàng là nguyên nhân điển hình gây ra lỗi 504.
- **Offload to Background Jobs:** Nếu một tác vụ mất hơn 10 giây (như gửi 50 email hoặc tạo tệp PDF), đừng để người dùng phải chờ đợi. Hãy sử dụng một hàng đợi (queue) như Celery hoặc Redis và trả về thông báo "Đang xử lý" ngay lập tức.
- **Inspect the Network:** Nếu Nginx và backend nằm trên các máy chủ khác nhau, độ trễ mạng có thể làm giảm thời gian chờ của bạn. Tôi thường sử dụng [Subnet Calculator](https://toolcraft.app/en/tools/developer/ip-subnet-calculator) này khi lập sơ đồ VPC để đảm bảo định tuyến nội bộ hiệu quả và không tạo ra các bước nhảy (hops) không cần thiết.

Tóm tắt

Lỗi 504 Gateway Time-out về cơ bản là cách Nginx thông báo rằng backend của bạn đang gặp khó khăn. Để khắc phục triệt để, bạn phải đồng bộ các giá trị timeout trên toàn bộ hệ thống: trình duyệt, bộ cân bằng tải, Nginx và cuối cùng là chính máy chủ ứng dụng. Nếu bất kỳ phần nào trong chuỗi này hết thời gian chờ quá sớm, toàn bộ yêu cầu sẽ thất bại.

Related Error Notes