我在 Ubuntu 18.08 上运行以下堆栈并将其定义为 docker-compose:
- 实例
mariadb:10.3.20
- 基于其上
wordpress:5.3.0-php7.2
安装的自定义 wordpress 实例ioncube
- 基于其上
nginx:1.13
安装的自定义 nginx 实例nginx-amplify-agent
nginx的配置:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10000;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 main_ext '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$host" sn="$server_name" '
'rt=$request_time '
'ua="$upstream_addr" us="$upstream_status" '
'ut="$upstream_response_time" ul="$upstream_response_length" '
'cs=$upstream_cache_status' ;
access_log /var/log/nginx/access.log main_ext;
error_log /var/log/nginx/error.log warn;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf;
}
site 定义如下:
server {
listen 80;
listen [::]:80;
server_name some.org www.some.org;
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name some.org www.some.org;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/some.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/some.org/privkey.pem;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
location / {
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_redirect off;
proxy_pass http://wordpress;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|js|gif|ico|jpeg|jpg|png)$ {
expires max;
log_not_found off;
}
}
整个堆栈按预期工作,除非有 10-15 个用户访问网站并尝试执行操作。在这种情况下,一些请求开始挂起(通常是对某个组件的相同 POST 请求),3-4 分钟后,它会被释放,没有任何错误,用户实际上可以看到它的结果。在挂起期间,网站不再对同一浏览器负责(但从其他浏览器一切正常!)。请求发布后 - 网站再次负责。
日志也很奇怪:
- 一旦挂起/待处理的请求到达服务器,它将显示在 nginx 访问日志中,但不显示在 wordpress 日志中
- 一旦请求最终被释放(即处理),它将在 nginx 访问日志和 wordpress 日志中第二次显示,但时间不同
nginx 访问日志:
62.96.39.243 - - [17/Jan/2020:10:56:41 +0000] "GET /something
78.43.40.52 - - [17/Jan/2020:10:56:41 +0000] "POST /ajax-bidsform.html?meth=post&yid=d7f9f1a1a0bf HTTP/2.0" 200 208 "https://some.org/xchange_XRP_to_SBERRUB/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" "-"
78.43.40.52 - - [17/Jan/2020:10:56:41 +0000] "GET /something
WordPress:
134.19.130.91 - - [17/Jan/2020:10:56:40 +0000] "GET /something
78.43.40.52 - - [17/Jan/2020:10:50:07 +0000] "POST /ajax-bidsform.html?meth=post&yid=d7f9f1a1a0bf HTTP/1.0" 200 559 "https://some.org/xchange_XRP_to_SBERRUB/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"
62.96.39.243 - - [17/Jan/2020:10:56:41 +0000] "GET /something
如您所见,POST /ajax-bidsform.html...
nginx 日志中的挂起时间为 10:56,而 wordpress 中的挂起时间为 10:50 - 这正是客户端完成此请求的时间。据我所知,这意味着请求在 nginx 级别的某个地方停留了近 6 分钟,直到它真正传递给 wordpress。如您所见,我没有 nginx 的 ddos 保护指令。
另外,我这边还有一些注意事项:在挂起请求期间,没有任何 CPU 或 RAM 长期峰值,因此可能与硬件问题无关。我还认为它与挂起脚本(即ajax-bidsform.html
)有某种关系,但只有当我们从虚拟主机迁移到 digital-ocean 的云实例时才会发生这种情况(以前从未发生过),所以我猜这是一个配置问题。日志中的请求时间线也证明了这一点。
到目前为止我确实尝试过:
- 增加
worker_connections
至 10000 - 将 nginx 实例(不是主机的实例)增加到
net.core.somaxconn
1024
但问题仍然存在......任何想法或意见都将不胜感激!
答案1
nginx 日志中为 10:56,但 wordpress 中为 10:50
我会将其解释为 wordpress 在 10:50 接收请求并在 10:56 将结果返回给 nginx。要确定,您可以在 nginx 中添加。请upstream_response_time
参阅log_format
使用 NGINX 日志进行应用程序性能监控。