MeWrite Docs

504 Gateway Timeout

バックエンドサーバーからの応答がタイムアウトした場合に発生するエラー

概要

504 Gateway Timeout は、Nginxがリバースプロキシとして動作している際に、バックエンドサーバー(PHP-FPM、uWSGI、Node.js等)からの応答が制限時間内に得られなかった場合に発生するエラーです。

エラーメッセージ

504 Gateway Time-out
nginx
upstream timed out (110: Connection timed out) while reading response header from upstream

原因

  1. バックエンドの処理が遅い: 重い処理やクエリに時間がかかる
  2. タイムアウト設定が短い: Nginx のプロキシタイムアウトが不十分
  3. バックエンドが応答しない: PHP-FPM やアプリケーションがハング
  4. リソース不足: CPU、メモリ、接続数の枯渇
  5. ネットワークの問題: バックエンドへの接続が遅い

解決策

1. Nginx のタイムアウト設定を増やす

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# /etc/nginx/nginx.conf または /etc/nginx/conf.d/default.conf

http {
    # プロキシのタイムアウト設定
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;

    # FastCGI (PHP-FPM) のタイムアウト設定
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 60s;
    fastcgi_read_timeout 60s;

    # uWSGI のタイムアウト設定
    uwsgi_connect_timeout 60s;
    uwsgi_send_timeout 60s;
    uwsgi_read_timeout 60s;
}
1
2
3
4
5
# location ブロックで個別に設定
location /api/slow-endpoint {
    proxy_pass http://backend;
    proxy_read_timeout 300s;  # 5分
}

2. PHP-FPM のタイムアウト設定

1
2
3
4
5
6
7
8
; /etc/php/8.2/fpm/pool.d/www.conf

; リクエストのタイムアウト(0は無制限)
request_terminate_timeout = 300

; スローログのしきい値
request_slowlog_timeout = 10s
slowlog = /var/log/php-fpm/slow.log
1
2
; /etc/php/8.2/fpm/php.ini
max_execution_time = 300

3. バックエンドの接続設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# upstream の設定
upstream backend {
    server 127.0.0.1:9000;

    # 接続のキープアライブ
    keepalive 32;
}

server {
    location ~ \.php$ {
        fastcgi_pass backend;
        fastcgi_keep_conn on;

        # バッファ設定
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
    }
}

4. Node.js / Express の設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// server.js
const express = require('express');
const app = express();

// サーバータイムアウト
const server = app.listen(3000);
server.setTimeout(300000);  // 5分

// 特定のルートでタイムアウトを延長
app.get('/api/slow', (req, res) => {
    req.setTimeout(300000);  // リクエストのタイムアウト
    res.setTimeout(300000);  // レスポンスのタイムアウト
    // 処理
});
1
2
3
4
5
6
7
# Nginx の設定
location /api/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_read_timeout 300s;
}

5. uWSGI の設定

1
2
3
4
5
; uwsgi.ini
[uwsgi]
http-timeout = 300
socket-timeout = 300
harakiri = 300
1
2
3
4
5
6
# Nginx
location / {
    uwsgi_pass unix:/run/uwsgi/app.sock;
    uwsgi_read_timeout 300s;
    include uwsgi_params;
}

6. Gunicorn の設定

1
2
# 起動時にタイムアウトを設定
gunicorn app:app --timeout 300 --workers 4
1
2
3
# gunicorn.conf.py
timeout = 300
workers = 4

7. バックエンドの処理を最適化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// PHP - 重いクエリを最適化
// ❌ N+1 クエリ
foreach ($users as $user) {
    $orders = Order::where('user_id', $user->id)->get();
}

// ✅ Eager Loading
$users = User::with('orders')->get();

// インデックスを確認
// EXPLAIN SELECT * FROM orders WHERE user_id = 1;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Python - 非同期処理に変更
# ❌ 同期処理
def slow_endpoint():
    result = heavy_computation()
    return result

# ✅ バックグラウンドタスクに移行
from celery import Celery

@celery.task
def heavy_computation_task():
    return heavy_computation()

def slow_endpoint():
    task = heavy_computation_task.delay()
    return {'task_id': task.id}

8. ヘルスチェックの設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
upstream backend {
    server 127.0.0.1:9000;

    # ヘルスチェック(Nginx Plus)
    # health_check interval=10s fails=3 passes=2;
}

# 簡易ヘルスチェック
location /health {
    proxy_pass http://backend/health;
    proxy_connect_timeout 5s;
    proxy_read_timeout 5s;
}

9. キャッシュの活用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# プロキシキャッシュの設定
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;

server {
    location /api/ {
        proxy_cache my_cache;
        proxy_cache_valid 200 10m;
        proxy_cache_use_stale error timeout updating;
        proxy_pass http://backend;
    }
}

デバッグのコツ

Nginx のエラーログ

1
2
3
4
5
# エラーログを確認
tail -f /var/log/nginx/error.log

# デバッグレベルを上げる
error_log /var/log/nginx/error.log debug;

バックエンドの状態確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# PHP-FPM の状態
sudo systemctl status php8.2-fpm
tail -f /var/log/php-fpm/error.log

# プロセスの確認
ps aux | grep php-fpm
ps aux | grep node

# 接続数の確認
netstat -an | grep :9000 | wc -l

スローログの確認

1
2
3
4
5
# PHP-FPM スローログ
tail -f /var/log/php-fpm/slow.log

# MySQL スロークエリログ
tail -f /var/log/mysql/slow.log

Nginx の他のエラー

最終更新: 2025-12-08