我使用 Laravel Forge 来启动我的 EC2 环境,这为我创建了一个 LEMP 堆栈。我最近开始收到 504 次请求超时。

我不是系统管理员(因此订阅了 Forge),但我查看了日志并将问题缩小到我日志中的这 2 个重复条目:

在:/var/log/nginx/default-error.log

2017/09/15 09:32:17 [error] 2308#2308: *1 upstream timed out (110: Connection timed out) while sending request to upstream, client: x.x.x.x, server: xxxx.com, request: "POST /upload HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/php7.1-fpm.sock", host: "xxxx.com", referrer: "https://xxxx.com/rest/of/the/path"

在:/var/log/php7.1-fpm-log
[15-Sep-2017 09:35:09] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 14 total children

似乎 fpm 打开了永不消亡的连接,并且从我的 RDS 负载日志中我可以看到 RAM 不断被最大化。

我试过了:
  • 回滚到我的应用程序的明确稳定版本(2 个月前)
  • 使用 5.6、7.0 和 7.1 重新安装我的 EC2 (以及它们各自的 fpm )
  • 在 14.04 和 16.04 上执行上述所有操作
  • 创建更大的 RDS

  • 现在唯一有效的是强大的 RDS(8GB RAM)+每 300 个请求杀死 fpm 池连接。但显然在这个问题上投入资源并不是解决方案。

    这是我的 /etc/php/7.1/fpm/pool.d/www.conf 配置
    user = forge
    group = forge
    listen = /run/php/php7.1-fpm.sock
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0666
    pm = dynamic
    pm.max_children = 30
    pm.start_servers = 7
    pm.min_spare_servers = 6
    pm.max_spare_servers = 10
    pm.process_idle_timeout = 7s;
    pm.max_requests = 300
    

    这是我的 nginx.conf 配置
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name xxxx.com;
    root /home/forge/xxxx.com/public;
    
    # FORGE SSL (DO NOT REMOVE!)
    ssl_certificate /etc/nginx/ssl/xxxx.com/111111/server.crt;
    ssl_certificate_key /etc/nginx/ssl/xxxx.com/111111/server.key;
    
    ssl_protocols xxxx;
    ssl_ciphers ...;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;
    
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    
    index index.html index.htm index.php;
    
    charset utf-8;
    
    # FORGE CONFIG (DOT NOT REMOVE!)
    include forge-conf/xxxx.com/server/*;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location = /favicon.ico
    location = /robots.txt
    
    access_log /var/log/nginx/xxxx.com-access.log;
    error_log  /var/log/nginx/xxxx.com-error.log error;
    
    error_page 404 /index.php;
    
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_read_timeout 60;
        include fastcgi_params;
    }
    
    location ~ /\.(?!well-known).* {
        deny all;
    }
    
    location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
    

    最佳答案

    好的,经过大量调试和测试后,我注意到了这几个原因。

  • 我的主要原因: 我用于 MySQL 的 AWS RDS 实例有 500Mb 的内存。回顾过去,所有这些问题都是在数据库大小超过 400Mb 时开始的。
  • 解决方案: 确保您始终拥有 2 倍于您的数据库大小的 RAM。否则整个 B+Tree 无法放入内存中,因此它必须进行不断的交换。这可能会使您的查询时间超过 15 秒。
  • 此类问题的主要原因: 未优化的 SQL 查询。
  • 解决方案: 在你的本地主机上维护与你服务器上数据大小相似的数据。
  • 关于PHP FPM 7.1 套接字泄漏导致 NGINX - 504 网关超时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46248790/

    10-12 06:01