PHP-FPM 与 nginx 负载平衡长请求会阻止所有其他请求

PHP-FPM 与 nginx 负载平衡长请求会阻止所有其他请求

我有三台服务器,负载均衡器运行 nginx 并将 PHP 请求上游传递到运行 php-fpm 的两台服务器之一。

我实际上首先尝试测试并发性,因此每个 PHP-FPM 服务器上的 php 脚本都会显示开始和结束时间以及主机名,并且在回显开始时间后,它会使用 100% 的 CPU 持续 5 秒,然后才回显结束时间。

对于 4 个并发请求,两台服务器均不会同时达到 100% CPU 占用,并且时间戳显示它们是连续服务的,这让我认为 nginx 和 fastcgi 阻止了所有并发连接。

运行具有 100 个并发连接的 ab 会看到一个 PHP-FPM 服务器(共 10 个可用)上的所有进程都在处理,而另一个服务器则完全安静地什么也不做。

nginx 配置如下:

upstream  backend  {
     server   192.168.1.60:9000;
    server   192.168.1.61:9000;  
}

server {
    listen   80;
    server_name  localhost;
    access_log  /var/log/nginx/localhost.access.log;

    location / {
        root   /var/www;
        index  index.php;
    }


    location ~ .php$ {
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   backend;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www$fastcgi_script_name;
        include fastcgi_params;
    }

}

答案1

不要通过网络传递 FCGI;尽可能使用常规 HTTP。你现在的做法是进入未经充分测试的领域。

无论如何,我真的不建议使用 nginx 作为负载平衡器。它真的不是最好的(甚至不是“足够好”)工具。我认为最好的选择是Linux 虚拟服务器,因为它对于 TCP 连接是透明的并且速度极快,但如果由于某种原因无法实现,至少也使用haproxy

答案2

我建议你做相反的事情。将此服务器保留为负载平衡器,并仅在后端进行 FPM 配置。如果 nginx 和 fpm 位于通过套接字或本地主机通信的同一台服务器中,则 FastCGI 会更好地发挥作用,因此它类似于以下设置:

                          ---- backend 1 with nginx + php fpm
server with two backends |
                          ---- backend 2 with nginx + php fpm

这样,如果有什么东西阻塞了其中一个后端,它就不会影响第二个后端,并且负载平衡器将继续从它那里提供服务。此外,即使您使用动态设置,也请务必调整 fpm 子项的数量。

答案3

如果你确实需要使用 FastCGI 服务器来代替 nginx + php-fpm 框架,你可以尝试使用 nginx 的 fair 模块这里。该插件评估每个后端的响应时间并分别轮换。请注意,这将要求您重新编译 nginx。

如果你不想这样,至少要确保你不是使用ip_hash指令,因为在基准上请求时不会发生旋转(因为源 IP 始终相同)并尝试least_conn(在 nginx >= 1.2.2 中发现)。更多信息这里。最后,使用以下方法调整 nginx 选择下一个服务器的标准:fastcgi_next_upstream

fastcgi_next_upstream timeout http_503 http_500 invalid_header

以缓解超载节点的超时问题。关于这一点,这里

相关内容