优化 Nginx + PHP-FPM,实现每日 500 万次浏览量


Optimize Nginx + PHP-FPM for 5 million daily pageviews

我们运营着一些高流量的网站,每天总共产生约500万次浏览量。我们拥有最矫枉过正的服务器,因为我们预计会增长,但我们有一些活跃用户报告说该网站有时在第一次页面浏览时很慢。我自己每隔一段时间就会看到这种情况,第一次浏览需要 3-5 秒,然后在一天的剩余时间里立即出现。在过去的 24 小时内,这种情况可能发生了两次,所以不足以弄清楚发生了什么。我们网站上的每个页面都使用PHP,但有一次发生在我身上的是没有任何数据库调用的PHP页面,这让我认为问题仅限于NGINX,PHP-FPM或网络设置。

我们有 3 个 NGINX 服务器在负载均衡器后面运行。我们的数据库在集群上是独立的。我包含了nginx和php-fpm的配置文件,以及我们当前的RAM使用情况和PHP-FPM状态。这是基于中午(我们的平均流量)。请查看一下,如果您在我的设置中看到任何危险信号或有任何进一步优化的建议,请告诉我。

每个NGINX服务器的规格:

OS: CentOS 7
RAM: 128GB
CPU: 32 cores (2.4Ghz each)
Drives: 2xSSD on RAID 1

内存使用情况(免费 -g)

              total        used        free      shared  buff/cache   available
Mem:            125          15          10           3         100         103
Swap:            15           0          15

PHP-FPM status (IE: http://server1_ip/status)

pool:                 www
process manager:      dynamic
start time:           03/Mar/2016:03:42:49 -0800
start since:          1171262
accepted conn:        69827961
listen queue:         0
max listen queue:     0
listen queue len:     0
idle processes:       1670
active processes:     1
total processes:      1671
max active processes: 440
max children reached: 0
slow requests:        0

php-fpm 配置文件:

[www]
user = nginx
group = nginx
listen = /var/opt/remi/php70/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 6000
pm.start_servers = 1600
pm.min_spare_servers = 1500
pm.max_spare_servers = 2000
pm.max_requests = 1000
pm.status_path = /status
slowlog = /var/opt/remi/php70/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/opt/remi/php70/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/opt/remi/php70/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/opt/remi/php70/lib/php/wsdlcache

nginx配置文件:

user nginx;
worker_processes 32;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
    worker_connections 1000;
    multi_accept        on;
    use                 epoll;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_iso8601] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   10 10;
    send_timeout    60;
    types_hash_max_size 2048;
    client_max_body_size 50M;
    client_body_buffer_size 5m;
    client_body_timeout 60;
    client_header_timeout 60;
    fastcgi_buffers 256 16k;
    fastcgi_buffer_size 128k;
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 60s;
    fastcgi_read_timeout 60s;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    reset_timedout_connection on;
    server_names_hash_bucket_size 100;

    #compression
    gzip  on;
    gzip_vary on;
    gzip_min_length 10240;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml;
    gzip_disable "MSIE [1-6]'.";
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  domain1.com;
        root         /folderpath;
        location / {
            index index.php;
        }
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

    #server status
        location /server-status {
            stub_status on;
        access_log off;
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
    location = /status {
        access_log off;
        allow 127.0.0.1;
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/.htpasswd;
            fastcgi_pass unix:/var/opt/remi/php70/run/php-fpm/php-fpm.sock;
            fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

        location ~ '.php$ {
            try_files $uri =404;
            fastcgi_pass unix:/var/opt/remi/php70/run/php-fpm/php-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }

更新:

我按照下面的建议安装了opcache。不确定它是否解决了问题。这是我的设置

opcache.enable=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=32531
opcache.max_wasted_percentage=10

2 个小提示:

  • 如果使用 opcache,请监视它以检查其配置(尤其是内存大小)是否正常,并避免 OOM 重置,您可以使用 https://github.com/rlerdorf/opcache-status(单个 PHP 页面)

  • 增加 pm.max_请求以继续使用相同的进程