0

我试图检查并阅读有关此错误的文章,但直到现在我无法解决此问题。我使用 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 检查了我的资源

htop

关于这个有什么提示吗?

4

2 回答 2

1

所以我根据这个答案提出了它:https ://serverfault.com/a/844462

并且轻松地使 Internet 上的任何人都能够立即关闭您的网站。

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

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从命令行到 GUI 工具,如 SEO Frog Spider。由于它们连续发出许多请求,从而导致 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 缓存(缓存所有内容策略)。

于 2019-11-16T23:09:15.497 回答
0

所以我检查了日志以验证问题所在。我没有进入服务器,所以当我旋转我的 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/

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

于 2019-11-16T08:31:28.783 回答