【问题标题】:Why does Error 502 show every now and then on my site even after upgrading my server?为什么即使在升级我的服务器后,错误 502 也会不时出现在我的网站上?
【发布时间】:2019-11-16 05:50:02
【问题描述】:

我尝试检查和阅读有关此错误的文章,但直到现在我无法解决此问题。我使用 Cloudflare 来保护我的网站。如何修复错误 502 Bad Gateway

我的网站目前在 Digital Ocean 上运行(PHP7.2 - Codeigniter 3、MySQL 和 Nginx),我最近升级了我的服务器,因为我认为这可能是由于我的网站流量。我以前用 5 美元的 droplet,现在我用 15 美元(2 个 vCPU 和 2GB 内存)。

Nginx 错误日志:https://pastebin.com/XjGGjNPL

这是配置:

server {
        listen 80;
        root /var/www/<site_dir>;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name <domain>;

        #location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
        #        expires max;
        #        log_not_found off;
        #}

        location / {
                try_files $uri $uri/ /index.php;
        }

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

        location ~ /\.ht {
                deny all;
        }

        # Deny for accessing codes
        location ~ ^/(application|system|tests)/ {
            return 403;
        }
}

server {
        listen 80 default_server;
        server_name _;
        return 404;
}

我使用 htop 检查了我的资源

对此有什么建议吗?

【问题讨论】:

    标签: php mysql nginx codeigniter-3 bad-gateway


    【解决方案1】:

    所以我按照这个答案提出来了:https://serverfault.com/a/844462

    并且轻松地让互联网上的任何人都能立即关闭您的网站。

    绝对没有任何情况下链接的答案可以有任何好处,但我将在下面解释为什么它对您的特定服务器规格不好。

    pm.max_children = 4000
    

    pm = ondemand 一起,这意味着当流量足够快时,PHP-FPM 将继续分叉越来越多的进程,直到最多有 4k 个子进程。一个典型的 PHP-FPM 工作进程平均消耗 80 MB 的 RAM。将其乘以 4k,仅此设置服务器就需要 320 GB (!!!) RAM。

    pm.max_requests = 0
    

    现在这个。它控制一个给定的 PHP-FPM 工作程序在被回收和替换为新的请求之前将处理多少个请求。您通常总是希望在某个时候回收 PHP-FPM 工作进程,因为 PHP 本身及其扩展本身就是一个内存泄漏倾向的软件。因此,如果没有进行回收,那么每个进程的平均 80 MB 很有可能随着时间的推移很容易变得越来越“胖”,因此即使 320 GB 的 RAM 也不足以处理流量。

    如何使用这些设置杀死一个网站:通过使用能够连续发出许多请求(甚至不需要并行)的任何软件,从命令行上的 curl 到 SEO 等 GUI 工具青蛙蜘蛛。由于它们连续发出许多请求,从而导致 PHP-FPM 工作人员几乎无限(高达 4k)分叉,最终您的服务器一旦达到内存条件,将开始终止进程​​以尝试获得空闲 RAM。

    这种杀戮的典型选择是 MySQL 进程,一旦它被内核牺牲 - 你的网站就会停止工作。

    至于如何以一种合理的方式配置 PHP-FPM,您需要实际测量 PHP-FPM 工作进程“权重”的多少才能正确设置 max_children

    但是,您可以根据需要进行简单的计算和进一步的微调。假设我们考虑到规定的平均值为 80 MB。拿你的服务器内存减去 MySQL “吃”的东西以及任何其他住宅程序。假设这是 500 MB。因此,您还有 1500 MB 的空间供 PHP-FPM 工作人员使用。

    1500 / 80 = 剩下pm.max_children=19

    当然,您需要:

    • pm.max_requests 最多调整为 10000(最安全的是 500 甚至更低,例如 100)。从不0(这意味着不回收)
    • 配置一些交换,这样即使这 19 个 PHP 工作进程也会导致内存不足的情况,您的网站仍然在线。

    当您监控一段时间内的交换使用情况时(free -m 是您的朋友),您可以了解进一步提高 PHP-FPM 工作人员是否安全,但如果有的话,使用现代框架,您可能会有每个工作人员超过 80 MB,您可能需要降低。

    但这就是正确使用 PHP-FPM 的方法。真正的解决方案是在您的应用程序内外进行高效缓存:

    内部:Codeigniter 缓存

    外部:Varnish、NGINX FastCGI 缓存

    更进一步:为 HTML 输出启用 Cloudflare 缓存(缓存所有内容策略)。

    【讨论】:

    • 我知道我来晚了,但感谢您的回答。我实际上用这个配置配置了 php-fpm:serverfault.com/a/844462。它工作正常,有时我的并发请求高于正常水平,我的网站变慢了。但我再也不会遇到错误 502。但是,由于该配置非常昂贵并且可能会关闭我的站点,因此我将尝试计算 pm.max_children 并查看结果。
    【解决方案2】:

    所以我检查了日志以验证问题所在。我没有进入服务器,所以我在旋转我的 droplet 时将其保留为默认值。

    在检查/var/log/php7.2-fpm.log 时显示:

    '警告:[pool www] 服务器已达到 pm.max_children 设置 (5),考虑提高它'

    所以我按照这个答案提出来了:https://serverfault.com/a/844462

    pm = ondemand
    pm.max_children = 4000
    pm.start_servers = 10
    pm.min_spare_servers = 10
    pm.max_requests = 0
    

    我还通过提升工作进程优化了 php-fpm。

    worker_processes  2; #my server has 2 vCPU cores
    worker_connections  1024;
    

    (https://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/)

    到目前为止,每当我的服务器遇到网络请求高峰时,这都解决了我的问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 2013-07-15
      • 2015-01-07
      相关资源
      最近更新 更多