Nginx 反向代理性能低下
Nginx reverse proxy low performance
为两个目的尝试配置 Nginx:
- 反向代理将请求重定向到本地tomcat服务器(端口443到10443监听
mcat)
- 镜像请求到后端服务器进行分析
由于我们在使用默认配置和镜像指令时遇到了非常低的性能,我们决定尝试使用反向代理来检查是否对服务器有影响,而且 nginx 似乎确实将流量限制了将近一半(我们使用的是 Locust 和 Jmeter 作为加载工具)
Nginx 版本:1.19.4
已完成 10-tips-for-10x-application-performance & 调整 NGINX 的性能
无济于事。
运行 nginx & tomcat 的机器应该足够强大(EC2 c5.4XLarge),我们没有看到资源不足,但网络上限更多。 TIME_WAIT 连接数非常高 (20k-40k)
从机器角度看:
- 增加网络端口范围 (1024 65300)
- 降低 tcp_fin_timeout(15 毫秒)
- 将最大 FD 增加到最大值
Nginx视角(后加nginx.conf):
- keepalive_requests100000;
keepalive_timeout1000;
- worker_processes 10(16 是 cpu 计数)
- worker_connections 3000;
- worker_rlimit_nofile 100000;
nginx.conf:
user nginx;
worker_processes 10;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 100000;
events {
worker_connections 3000;
}
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' ;
keepalive_requests 100000;
keepalive_timeout 1000;
ssl_session_cache shared:SSL:10m;
sendfile on;
#tcp_nopush on;
#gzip on;
include /etc/nginx/conf.d/*.conf;
upstream local_host {
server 127.0.0.1:10443;
keepalive 128;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/nginx/crt.pem;
ssl_certificate_key /etc/ssl/nginx/key.pem;
location / {
# mirror /mirror;
proxy_set_header Host $host;
proxy_pass https://local_host$request_uri;
}
# Mirror configuration
location = /mirror {
internal;
proxy_set_header Host test-backend-dns;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 3s;
proxy_read_timeout 100ms;
proxy_send_timeout 100s;
proxy_pass https://test-backend-ip:443$request_uri;
}
}
}
也用Amplify代理监控,连接数似乎符合预期的请求数和连接数,但实际请求数很少。
Amplify monitor output
对于 Nginx 来说似乎是一项简单的任务,但配置有误。
谢谢你的回答
经过多次尝试和解决问题的方法后,我们得出结论,使用 nginx 的应用程序响应时间更长。
我们的假设以及我们最终如何克服这个问题,是 SSL 终止。
从资源和时间两方面来看,这是一项昂贵的操作。
我们所做的是让 nginx(它能够处理比我们遇到的负载高得多的负载,~4k RPS)仅负责 SSL 终止,我们更改了 tomcat 应用程序配置,使其监听 HTTP 请求而不是 HTTPS。
这大大减少了 TIME_WAIT 连接,这些连接正在打包并从服务器获取重要资源。
nginx、tomcat 和内核的最终配置:
linux机器配置:
- /proc/sys/net/ipv4/ip_local_port_range - set to 1024 65535
(allows more ports hence ---> more connections)
- sysctl net.ipv4.tcp_timestamps=1
(""..reduce performance spikes related to timestamp generation..")
- sysctl net.ipv4.tcp_tw_recycle=0
(This worked for us. Should be tested with/without tcp_tw_reuse)
- sysctl net.ipv4.tcp_tw_reuse=1
(Same as tw_recycle)
- sysctl net.ipv4.tcp_max_tw_buckets=10000
(self explanatory)
Redhat explanation for tcp_timeouts conf
Tomcat配置:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="4000"
minSpareThreads="10"
/>
<!-- A "Connector" using the shared thread pool - NO SSL -->
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
acceptCount="5000"
pollerThreadCount="16"
acceptorThreadCount="16"
redirectPort="8443"
/>
Nginx 特定性能参数配置:
main directive:
- worker_processes auto;
- worker_rlimit_nofile 100000;
events directive:
- worker_connections 10000; (we think can be lower)
- multi_accept on;
http directive:
- keepalive_requests 10000;
- keepalive_timeout 10s;
- access_log off;
- ssl_session_cache shared:SSL:10m;
- ssl_session_timeout 10m;
真正有助于理解等式的两点:Nginx 和 tomcat。
我们使用 jmx 指标来了解 tomcat 以及我们应用中的 prometheus 指标。
Amplify agent 监控 nginx 行为。
希望对大家有所帮助。
为两个目的尝试配置 Nginx:
- 反向代理将请求重定向到本地tomcat服务器(端口443到10443监听 mcat)
- 镜像请求到后端服务器进行分析
由于我们在使用默认配置和镜像指令时遇到了非常低的性能,我们决定尝试使用反向代理来检查是否对服务器有影响,而且 nginx 似乎确实将流量限制了将近一半(我们使用的是 Locust 和 Jmeter 作为加载工具)
Nginx 版本:1.19.4
已完成 10-tips-for-10x-application-performance & 调整 NGINX 的性能 无济于事。 运行 nginx & tomcat 的机器应该足够强大(EC2 c5.4XLarge),我们没有看到资源不足,但网络上限更多。 TIME_WAIT 连接数非常高 (20k-40k)
从机器角度看:
- 增加网络端口范围 (1024 65300)
- 降低 tcp_fin_timeout(15 毫秒)
- 将最大 FD 增加到最大值
Nginx视角(后加nginx.conf):
- keepalive_requests100000; keepalive_timeout1000;
- worker_processes 10(16 是 cpu 计数)
- worker_connections 3000;
- worker_rlimit_nofile 100000;
nginx.conf:
user nginx;
worker_processes 10;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 100000;
events {
worker_connections 3000;
}
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' ;
keepalive_requests 100000;
keepalive_timeout 1000;
ssl_session_cache shared:SSL:10m;
sendfile on;
#tcp_nopush on;
#gzip on;
include /etc/nginx/conf.d/*.conf;
upstream local_host {
server 127.0.0.1:10443;
keepalive 128;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/nginx/crt.pem;
ssl_certificate_key /etc/ssl/nginx/key.pem;
location / {
# mirror /mirror;
proxy_set_header Host $host;
proxy_pass https://local_host$request_uri;
}
# Mirror configuration
location = /mirror {
internal;
proxy_set_header Host test-backend-dns;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 3s;
proxy_read_timeout 100ms;
proxy_send_timeout 100s;
proxy_pass https://test-backend-ip:443$request_uri;
}
}
}
也用Amplify代理监控,连接数似乎符合预期的请求数和连接数,但实际请求数很少。 Amplify monitor output
对于 Nginx 来说似乎是一项简单的任务,但配置有误。 谢谢你的回答
经过多次尝试和解决问题的方法后,我们得出结论,使用 nginx 的应用程序响应时间更长。
我们的假设以及我们最终如何克服这个问题,是 SSL 终止。 从资源和时间两方面来看,这是一项昂贵的操作。
我们所做的是让 nginx(它能够处理比我们遇到的负载高得多的负载,~4k RPS)仅负责 SSL 终止,我们更改了 tomcat 应用程序配置,使其监听 HTTP 请求而不是 HTTPS。 这大大减少了 TIME_WAIT 连接,这些连接正在打包并从服务器获取重要资源。
nginx、tomcat 和内核的最终配置:
linux机器配置:
- /proc/sys/net/ipv4/ip_local_port_range - set to 1024 65535
(allows more ports hence ---> more connections)
- sysctl net.ipv4.tcp_timestamps=1
(""..reduce performance spikes related to timestamp generation..")
- sysctl net.ipv4.tcp_tw_recycle=0
(This worked for us. Should be tested with/without tcp_tw_reuse)
- sysctl net.ipv4.tcp_tw_reuse=1
(Same as tw_recycle)
- sysctl net.ipv4.tcp_max_tw_buckets=10000
(self explanatory)
Redhat explanation for tcp_timeouts conf
Tomcat配置:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="4000"
minSpareThreads="10"
/>
<!-- A "Connector" using the shared thread pool - NO SSL -->
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
acceptCount="5000"
pollerThreadCount="16"
acceptorThreadCount="16"
redirectPort="8443"
/>
Nginx 特定性能参数配置:
main directive:
- worker_processes auto;
- worker_rlimit_nofile 100000;
events directive:
- worker_connections 10000; (we think can be lower)
- multi_accept on;
http directive:
- keepalive_requests 10000;
- keepalive_timeout 10s;
- access_log off;
- ssl_session_cache shared:SSL:10m;
- ssl_session_timeout 10m;
真正有助于理解等式的两点:Nginx 和 tomcat。
我们使用 jmx 指标来了解 tomcat 以及我们应用中的 prometheus 指标。 Amplify agent 监控 nginx 行为。
希望对大家有所帮助。