繁体   English   中英

Nginx和php-fpm:无法摆脱502和504错误

[英]Nginx and php-fpm: cannot get rid of 502 and 504 errors

我有一个ubuntu服务器和一个相当高的网站。 服务器是:

  • 专用于nginx,使用php-fpm(没有apache),mysql位于不同的机器上
  • 有8 GB的RAM
  • 每秒获取大约2000个请求。

根据top命令,每个php-fpm进程消耗大约65MB的RAM:

顶级命令

空闲记忆:

admin@myserver:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          7910       7156        753          0        284       2502
-/+ buffers/cache:       4369       3540
Swap:         8099          0       8099

问题

最近,我遇到了很大的性能问题。 非常大的响应时间,非常多的Gateway Timeouts和晚上,当负载变高时,90%的用户只看到“找不到服务器”而不是网站(我似乎无法重现这一点)


日志

我的Nginx错误日志充满了以下消息:

2012/07/18 20:36:48 [error] 3451#0: *241904 upstream prematurely closed connection while reading response header from upstream, client: 178.49.30.245, server: example.net, request: request: "GET /readarticle/121430 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9001", host: "example.net", referrer: "http://example.net/articles"

我已经尝试过切换到unix socket,但仍然会遇到这些错误:

2012/07/18 19:27:30 [crit] 2275#0: *12334 connect() to unix:/tmp/fastcgi.sock failed (2: No such file or directory) while connecting to upstream, client: 84.
237.189.45, server: example.net, request: "GET /readarticle/121430 HTTP/1.1", upstream: "fastcgi://unix:/tmp/fastcgi.sock:", host: "example.net", referrer: "http
://example.net/articles"

php-fpm日志中包含以下内容:

[18-Jul-2012 19:23:34] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there  are 0 idle, and 75 total children

我试图将给定参数增加到100 ,但似乎还不够。


CONFIGS

这是我目前的配置

PHP-FPM

listen = 127.0.0.1:9001
listen.backlog = 4096
pm = dynamic
pm.max_children = 130
pm.start_servers = 40
pm.min_spare_servers = 10
pm.max_spare_servers = 40
pm.max_requests = 100

nginx的

worker_processes  4;
worker_rlimit_nofile 8192;
worker_priority 0;
worker_cpu_affinity 0001 0010 0100 1000;

error_log  /var/log/nginx_errors.log;

events {
    multi_accept off;
    worker_connections  4096;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log off;
    sendfile        on;
    keepalive_timeout  65;
    gzip  on;

    # fastcgi parameters
    fastcgi_connect_timeout 120;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 1000;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

    client_max_body_size 128M;

    server {
        server_name example.net;
        root /var/www/example/httpdocs;
        index index.php;
        charset utf-8;
        error_log /var/www/example/nginx_error.log;

        error_page 502 504 = /gateway_timeout.html;

        # rewrite rule
        location / {
            if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php?path=$1 last;
            }
        }
        location ~* \.php {
            fastcgi_pass 127.0.0.1:9001;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

对于如何识别问题以及我可以调整哪些参数来解决这个问题,我将非常感激。 或者8GB的RAM对于这种负载来说还不够?

一些问题。 仍然值得用这么繁忙的网站修复它们。 MySQL可能是现在的根本原因。 但从长远来看,你需要做更多的工作。

高速缓存

我看到你的一个错误消息显示对php上游的get请求。 对于如此高流量的站点(如你所提到的2000 r / s),这看起来不太好。 这个页面(/ readarticle / 121430)似乎是一个完全可缓存的页面。 首先,您可以使用nginx缓存此类页面。 查看fastcgi缓存

GET /readarticle/121430

PHP-FPM

pm.max_requests = 100

该值表示在提供100个请求后,php-fpm master将终止进程。 php-fpm使用该值来对抗第三方内存泄漏。 您的网站非常繁忙,速度为2000r / s。 您的最大子进程为130,每个进程最多只能提供100个请求。 这意味着在13000/2000 = 6.5秒后,所有这些都将被回收。 这太过分了(每秒有20个进程被杀死)。 只要您没有看到内存泄漏,您至少应该以1000的值开头并增加该数字。 有人在生产中使用10,000。

nginx.conf

  • 问题1:

      if (!-e $request_filename) { rewrite ^(.*)$ /index.php?path=$1 last; } 

    应该用更高效的try_files替换:

      try_files $uri /index.php?path=$uri; 

如果位置块和正则表达式重写规则匹配,则保存额外的内容。

  • 问题2:使用unix socket比使用ip节省更多时间(根据我的经验,大约10-20%)。 这就是php-fpm将其用作默认值的原因。

  • 问题3:您可能有兴趣在nginx和php-fpm之间建立keepalive连接。 给出一个例子这里在nginx的官方网站。

我需要看看你的php.ini设置,我不认为这与MySQL有关,因为你看到它的套接字错误。 此外,这是在一段时间后开始发生的事情还是在服务器重新启动时立即发生?

尝试重新启动php5-fpm守护程序,看看在查找错误日志时会发生什么。

检查您的php.ini文件以及通常位于/ etc / nginx / fastcgi_params中的所有fastcgi_params。 你要做的事情有很多例子。

另外,你是否启用了apc php缓存扩展?

如果您在灯堆上,它将在您的php.ini文件中看起来像这样:

延长= apc.so
....
apc.enabled = 0

从命令行进行一些mysql连接负载测试也可能不会受到影响,看看结果如何。

设置nginx微型也会有所帮助。 这将在几秒钟内提供相同的响应。

http://seravo.fi/2013/optimizing-web-server-performance-with-nginx-and-php有关于nginx性能的一些很好的信息。 亲自跟着那个,我很开心。

为了得到这个问题的答案:

You should check your MySQL server. Probably it's overloaded or it limits count of parallel MySQL connections. You should find the bottleneck. And according to your top screenshot it doesn't look like either RAM or CPU, then it's most likely I/O. - @VBrat

您可能希望将来做的事情:

1-增加RAM大小。

2-使用缓存。 请参阅此文章 ,了解缓存如何加快您的网站速度

3-减少执行的查询数量。

  • 设置PHP的APC扩展(检查/配置)
  • MySQL - 检查配置,索引,慢查询
  • 安装和配置Varnish。 这可以缓存页面请求,并且在减少需要进行的php请求和mysql查询的数量方面非常有用。 使用cookies / ssl可能会很棘手但不是太困难而且非常值得运行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM