MySQL、php-fpm、APC、Varnish 和 Nginx 针对 WordPress/W3 Total Cache 进行优化?

MySQL、php-fpm、APC、Varnish 和 Nginx 针对 WordPress/W3 Total Cache 进行优化?

我正在设置我的第一个 VPS,它似乎运行良好。使用 OnApp 在 Ubuntu 12.04 服务器上安装了 Nginx、php-fpm(作为 unix 套接字)、APC、Varnish 和 MySQL,一切都运行正常,而且速度非常快,至少在我这边是这样。

目前我有一个 VPS,它有 1 个核心(如果我没记错的话,VPS 使用的是 Xeon(R) X5660),1.2GHz 和 768MB RAM,所有功能都受 OnApp 限制。进行 ab 测试后,我得到了以下结果:

ab -c 10 -n 1000 http://198.136.50.39/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 198.136.50.39 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        
Server Hostname:        198.136.50.39
Server Port:            80

Document Path:          /
Document Length:        6482 bytes

Concurrency Level:      10
Time taken for tests:   41.695 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      6952000 bytes
HTML transferred:       6482000 bytes
Requests per second:    23.98 [#/sec] (mean)
Time per request:       416.946 [ms] (mean)
Time per request:       41.695 [ms] (mean, across all concurrent requests)
Transfer rate:          162.83 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      167  203  57.3    182     614
Processing:   173  212  82.9    189    2015
Waiting:      169  206  59.8    185     726
Total:        345  415 126.5    373    2419

Percentage of the requests served within a certain time (ms)
  50%    373
  66%    388
  75%    410
  80%    430
  90%    504
  95%    708
  98%    866
  99%    931
 100%   2419 (longest request)

当我进行测试时,我用 htop 查看了 VPS 的统计数据,似乎整个测试中它使用的 RAM 不超过 230mb,CPU 使用率保持在 2~4%,我想这很酷。但似乎每秒请求数有点低。你们觉得呢?对于我的设置来说,这看起来还好吗?我有点偏执,还是它很糟糕?使用默认设置,我使用 loadimpact.com 进行了查看,有 25 个用户(默认免费测试),默认加载为 130ms... 在我开始弄乱设置后,再次进行测试,它跳到了 250ms,所以我猜我做错了什么。

我开始尝试优化 MySQL,使用我在网上找到的针对低端机器的教程,https://tools.percona.com/。Percona 给了我一些非常大的数字,所以我将两者混合起来。

我还优化了 php-fpm 和 Nginx,阅读了互联网上的维基和教程。我将使用这个 VPS 来运行一个 WordPress 网站,该网站每天大约有 5000 名访问者,每天有 13~15000 个页面浏览量。W3 Total Cache 设置为使用 APC 进行数据库和对象缓存,并使用磁盘增强功能进行最小化/页面缓存...但在我将网站迁移到此服务器并上线之前,我想优化所有内容并确保它运行速度很快。

我也使用 MaxCDN(目前在 VPS 上未启用),并将使用 CloudFlare 作为 DNS 服务器。有人能帮我优化一下吗?

我的 MySQL 配置目前如下所示:

[mysqld_safe]
open_files_limit = 8192

[mysqld]
skip_external_locking
skip_slave_start
bind-address        = 127.0.0.1
key_buffer      = 64M
join_buffer_size        = 1M
read_buffer_size        = 1M
sort_buffer_size        = 2M
max_allowed_packet  = 16M
max_connect_errors      = 10
thread_stack        = 192K
myisam-recover         = BACKUP
max_connections        = 400
table_cache            = 1024
thread_cache_size      = 286
interactive_timeout    = 25
wait_timeout           = 1000
query_cache_type    = 1
query_cache_limit   = 1M
query_cache_size        = 32M
max_write_lock_count = 1
expire_logs_days    = 10
max_binlog_size         = 100M

innodb_flush_method            = O_DIRECT
innodb_buffer_pool_size        = 10M

skip_name_resolve
sql_mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY

tmp_table_size      = 16M
max_heap_table_size = 16M

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer      = 16M

我的 Nginx 配置如下:

worker_processes 1;

events {
    worker_connections 1024;
}

http {

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    server_tokens off;

    open_file_cache max=1000 inactive=300s;
    open_file_cache_valid 360s;
    open_file_cache_min_uses 2;
    open_file_cache_errors off;

        client_body_buffer_size 8K;
        client_header_buffer_size 1k;
        client_max_body_size 2m;
        large_client_header_buffers 2 1k;

        client_body_timeout   10;
        client_header_timeout 10;
        send_timeout          10;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 9;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

我的网站的 Nginx 配置如下:

server {

    listen 8080;
    server_name www.ubuntubrsc.com ubuntubrsc.com;

    root /var/www;
    index index.php index.html index.htm;
        include /var/www/nginx.conf;

        error_log /var/log/nginx/blog.error_log;

        if ($host ~* ^[^.]+\.[^.]+$) {
        rewrite ^(.*)$ http://www.$host$1 permanent;
        }

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

        location = /favicon.ico {
    log_not_found off;
    access_log off;
        }

        location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
        }

        location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
        }

        location ~* ^/wp-content/uploads/.*.php$ {
    deny all;
    access_log off;
    log_not_found off;
        }

        rewrite /wp-admin$ $scheme://$host$uri/ permanent;

        location ~ \.(css|js|htc)$ {
        root /var/www/ubuntu-online/;
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
        }
        location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
        root /var/www/ubuntu-online/;
        expires 3600s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=3600, public, must-revalidate, proxy-revalidate";
        }
        location ~ \.(gif|gz|gzip|ico|jpg|jpeg|jpe|swf)$ {
        root /var/www/ubuntu-online/;
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
        }

    error_page 404 = @wordpress;
    log_not_found off;

    location @wordpress {
        include /etc/nginx/fastcgi_params;      
        fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_param SCRIPT_NAME /index.php;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        }

    location ~ \.php$ {
                try_files $uri =404;

        include /etc/nginx/fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        if (-f $request_filename) {
                fastcgi_pass unix:/var/run/php5-fpm.sock;
            }
    }
      }

ubuntu-online 的缓存部分是因为我不知道 W3 Total Cache 的设置是否适用于 /www/var/ 内的所有文件夹,所以我添加了带有“root /var/www/ubuntu-online/”的文件夹以确保无误。我应该删除它们吗?

在 php.ini 上我编辑了一些内容来增加安全性,比如 open_basedir 和其他内容,还通过编辑两行启用了 php 内部缓存,但不记得它是什么了。

此外,这些是 APC 设置:

[APC]
apc.enabled = 1
apc.cache_by_default = 1
apc.stat = 1
apc.shm_segments = 1
apc.shm_size = 64
apc.ttl = 7200

最后,我的 php-fpm 池:

listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

另外,我怎么知道 Varnish 是否与 WordPress 兼容?我知道我必须进行一些特定的配置才能让 Varnish 和 WordPress 很好地协同工作,我确实遵循了这一点https://github.com/nicolargo/varnish-nginx-wordpress,但我怎么知道它是否有效?

提前感谢大家(:

答案1

您的负载设置得非常好。20rps 到 php 脚本足以满足每天 200k+ 的页面浏览量。

需要调整的内容是: innodb_buffer_pool_size = 10M - 这是非常小的值。innodb 中的所有活动数据都应适合缓冲池,从而为事务日志留出足够的空间。

worker_connections 1024;- 你可能很快就会用完它。我建议你使用 stubstatus 模块检查实际负载下的 nginx 连接,并在服务运行的最初几天对其进行调整。

您还可以增加 php 并发性pm.max_children = 9- 以利用额外的 RAM 和 CPU。如果您遇到 TCP 积压问题,请执行此操作(ss -nl

如果请求率较高和/或脚本速度较慢,则可能会达到 max_children 限制。如果脚本受 CPU 限制,则增加最大工作线程/进程将增加平均负载。

让我给你展示一下基本和近似的数学计算。你的脚本平均运行 100 毫秒,使用 5 毫秒的 CPU 时间(100 毫秒是磁盘/网络 IO 等待时间)。

如果每秒有超过 9*1000/100=90 个请求,您的 tcp 积压将开始增长,新的请求将等待一段时间才能启动。

您的脚本将消耗单个 CPU 核心的 90*10/1000 = 45% 的 CPU 用户时间。不算多,不是吗?

如果将 max_children 增加到 15,则每秒可能会有 150 个请求而不会减慢速度,但脚本可能会消耗 75% 的单核 CPU 时间。

除非负载过大,否则这很好。如果您没有足够的 CPU 或 RAM 来处理所选的并发性 - 您的服务器将达到平均负载 - 这意味着脚本将由于 CPU 拥塞而变慢。负载平均值约为 CPU 核心数的 2-4 倍的服务器通常响应足够。请求处理会稍慢一些,但您可以处理更高的请求率。如果您没有足够的 RAM - 服务器将开始交换、加载磁盘和限制 CPU。

因此,如果 max_children 太少,您将无法处理高请求率。如果太多,您的服务器将因高负载而挂起。

相关内容