我在数字海洋水滴上有一个 nginx 服务器,有 2 个 CPU 和 4gb 内存。
我正在运行几个小型 WP 网站,流量不大 - 但似乎我可以毫不费力地将服务器的 CPU 推到 100%。实际上,我只需发送 (1-2/秒) 硬刷新,服务器就会达到 100% 并抛出错误 500。
我对服务器管理和 Nginx 还很陌生,所以我尽我所能进行调试 - 但我总是回到我的配置不够好的问题。
服务器信息:
- 2 个 CPU
- 4GB 内存
- CentOS 7
- 灶神星
- 纯 Nginx
- 仅运行 WP 网站
Nginx 配置:
# Server globals
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log crit;
pid /var/run/nginx.pid;
# Worker config
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Main settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
client_header_buffer_size 1k;
client_body_buffer_size 128k;
client_max_body_size 10m;
output_buffers 1 32k;
postpone_output 1460;
large_client_header_buffers 4 4k;
keepalive_timeout 30 30;
reset_timedout_connection on;
server_tokens off;
server_name_in_redirect off;
server_names_hash_max_size 512;
server_names_hash_bucket_size 512;
# Log format
log_format main '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format bytes '$body_bytes_sent';
#access_log /var/log/nginx/access.log main;
access_log off;
# Mime settings
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Compression
gzip on;
gzip_static on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_buffers 8 64k;
gzip_types text/plain text/css text/javascript text/js text/xml application/json application/javascript application/x-javascript application/xml application/xml+rss application/x-font-ttf image/svg+xml font/opentype;
gzip_proxied any;
gzip_disable "MSIE [1-6]\.";
# Proxy settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
# Cloudflare https://www.cloudflare.com/ips
set_real_ip_from 199.27.128.0/21;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
#set_real_ip_from 2400:cb00::/32;
#set_real_ip_from 2606:4700::/32;
#set_real_ip_from 2803:f800::/32;
#set_real_ip_from 2405:b500::/32;
#set_real_ip_from 2405:8100::/32;
real_ip_header CF-Connecting-IP;
# SSL PCI Compliance
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# Error pages
error_page 403 /error/403.html;
error_page 404 /error/404.html;
error_page 502 503 504 /error/50x.html;
# Cache settings
proxy_cache_path /var/cache/nginx levels=2 keys_zone=cache:10m inactive=60m max_size=1024m;
proxy_cache_key "$host$request_uri $cookie_user";
proxy_temp_path /var/cache/nginx/temp;
proxy_ignore_headers Expires Cache-Control;
proxy_cache_use_stale error timeout invalid_header http_502;
proxy_cache_valid any 1d;
# Cache bypass
map $http_cookie $no_cache {
default 0;
~SESS 1;
~wordpress_logged_in 1;
}
# File cache settings
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
# Wildcard include
include /etc/nginx/conf.d/*.conf;
}
PHP-fpm:
pm = ondemand
pm.process_idle_timeout = 10s
pm.max_children = 3
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 2
pm.max_requests = 300
php_admin_value[memory_limit] = 256M
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
顶部截图 - imgur.com/a/n02VZ
答案1
问题
这不太可能是个问题,但我们不知道,因为您没有包含 top/atop 之类的信息。这是因为 Wordpress / PHP 效率低下,占用大量服务器资源。如果您愿意,您可以在服务器繁忙时发布 top / atop 的屏幕截图,但如果这些截图都是由 PHP 截取的,则没有必要。
解决方案
一个解决方案,也可能是最好的解决方案,就是缓存。缓存有两种类型。
页面缓存
在这种情况下,页面缓存通常是最佳选择。它仅适用于匿名用户,而不适用于已登录的用户。在许多网站上,匿名用户占流量的大部分,因此缓存他们可以带来巨大的好处。页面由用户生成,存储在 Nginx 页面缓存中,然后提供给下一个用户。Nginx 页面缓存通常位于 RAM 中,因此速度非常快。
缓存标头
要使页面缓存正常工作,您需要正确设置标头。可以使用一些 Wordpress 缓存插件来完成此操作,但我不使用它们,所以我在 Nginx 中执行此操作。我必须构建 Nginx 并添加正确的模块,这非常简单。
Wordpress 缓存
另一种缓存是由 Wordpress 中的插件完成的。它可以缓存数据库请求,这需要时间,还可以进行某种我不完全理解的对象缓存。这可以帮助匿名用户和登录用户。有时它会导致问题。
例子
我有一个关于这个的教程,这里。它涵盖了缓存、构建 Nginx 以及许多其他内容,例如使用内容分发网络 (CDN),这也可以加快速度。第一页有可下载的配置文件。Nginx 有一个关于微缓存的文章值得一读。
内容分发网络(CDN):
说到 CDN,如果您拥有超大规模网站,则可以将页面配置为可缓存,并将 CDN 配置为缓存页面。这意味着您的网站很少收到请求,只有登录用户和缓存刷新才会收到请求。这会影响您的服务器统计数据,并增加向用户提供过时数据的可能性。
Nginx 错误
Nginx 1.11.11 有一个错误,它有时会使用 100% 的 CPU。Nginx 1.11.12修复了这个问题。