Nginx 连接优化与调优
Connection Optimization and Tuning
概述
连接优化是提升Nginx性能的关键环节。通过合理配置连接参数、优化网络设置和调整系统限制,可以显著提升服务器的并发处理能力和响应性能。
1. 基础连接配置
1.1 工作进程和连接数
# 全局配置
user nginx;
worker_processes auto; # 自动检测CPU核心数
worker_rlimit_nofile 65535; # 工作进程文件描述符限制
events {
worker_connections 1024; # 每个工作进程的连接数
use epoll; # Linux下使用epoll
multi_accept on; # 允许一次接受多个连接
accept_mutex off; # 关闭accept锁,提高性能
}
http {
# 连接保持配置
keepalive_timeout 65;
keepalive_requests 1000;
# 客户端连接超时
client_header_timeout 60;
client_body_timeout 60;
send_timeout 60;
# 缓冲区配置
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
client_body_buffer_size 8k;
client_max_body_size 50m;
}
1.2 高并发优化配置
events {
worker_connections 4096;
use epoll;
multi_accept on;
accept_mutex off;
# 工作进程调度优化
worker_priority -5; # 提高工作进程优先级
worker_cpu_affinity auto; # CPU亲和性绑定
}
http {
# 连接池优化
keepalive_timeout 30;
keepalive_requests 10000;
# 减少系统调用
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 优化缓冲区
client_header_buffer_size 2k;
large_client_header_buffers 4 8k;
client_body_buffer_size 16k;
server {
listen 80 backlog=4096 reuseport;
server_name high-performance.example.com;
location / {
proxy_pass http://backend;
# 后端连接优化
proxy_http_version 1.1;
proxy_set_header Connection "";
# 连接超时优化
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
}
}
}
2. 上游连接优化
2.1 连接池配置
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
# 连接保持
keepalive 32;
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
listen 80;
server_name backend.example.com;
location / {
proxy_pass http://backend;
# HTTP/1.1连接复用
proxy_http_version 1.1;
proxy_set_header Connection "";
# 连接缓冲优化
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
# 连接超时精细控制
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
}
}
2.2 负载均衡连接优化
upstream optimized_backend {
# 最少连接算法
least_conn;
server 192.168.1.10:8080 weight=3 max_conns=100;
server 192.168.1.11:8080 weight=2 max_conns=80;
server 192.168.1.12:8080 weight=1 max_conns=50 backup;
# 连接池配置
keepalive 64;
keepalive_requests 10000;
keepalive_timeout 300s;
# 队列配置
queue 100 timeout=30s;
}
server {
listen 80;
server_name lb.example.com;
# 连接限制
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_conn conn_limit 20;
location / {
proxy_pass http://optimized_backend;
# 连接复用
proxy_http_version 1.1;
proxy_set_header Connection "";
# 故障快速切换
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
}
3. SSL/TLS连接优化
3.1 SSL会话复用
server {
listen 443 ssl http2;
server_name ssl-optimized.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets on;
# SSL协议优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# OCSP装订
ssl_stapling on;
ssl_stapling_verify on;
# SSL缓冲区优化
ssl_buffer_size 4k;
location / {
root /var/www/html;
}
}
3.2 HTTP/2优化
server {
listen 443 ssl http2;
server_name http2.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# HTTP/2特定优化
http2_max_field_size 16k;
http2_max_header_size 32k;
http2_max_requests 10000;
http2_recv_timeout 30s;
http2_idle_timeout 180s;
location / {
# 推送关键资源
http2_push /css/main.css;
http2_push /js/main.js;
root /var/www/html;
}
# 服务器推送策略
location = /index.html {
# 智能推送
if ($http_user_agent ~* "Chrome") {
http2_push /css/chrome-optimized.css;
}
root /var/www/html;
}
}
4. 系统级优化
4.1 内核参数调优
#!/bin/bash
# system-tuning.sh
# TCP连接优化
echo "优化TCP连接参数..."
# 增加系统文件描述符限制
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
# TCP内核参数优化
cat >> /etc/sysctl.conf << EOF
# 网络连接优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 6000
# TCP连接复用
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
# 内存优化
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 拥塞控制
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF
# 应用配置
sysctl -p
echo "系统优化完成!"
4.2 进程和资源限制
#!/bin/bash
# nginx-limits.sh
# 创建nginx专用配置
cat > /etc/systemd/system/nginx.service.d/limits.conf << EOF
[Service]
LimitNOFILE=65535
LimitNPROC=32768
LimitCORE=infinity
EOF
# 创建专用的limits配置
cat > /etc/security/limits.d/nginx.conf << EOF
nginx soft nofile 65535
nginx hard nofile 65535
nginx soft nproc 32768
nginx hard nproc 32768
EOF
# 重新加载systemd配置
systemctl daemon-reload
systemctl restart nginx
echo "Nginx资源限制配置完成!"
5. 连接监控和分析
5.1 连接状态监控
# 状态监控页面
server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
location /connection_status {
content_by_lua_block {
-- 获取连接统计信息
local status = {}
-- 活跃连接数
status.active_connections = ngx.var.connections_active or 0
status.reading_connections = ngx.var.connections_reading or 0
status.writing_connections = ngx.var.connections_writing or 0
status.waiting_connections = ngx.var.connections_waiting or 0
-- 总请求数
status.total_requests = ngx.var.request_id or 0
ngx.header.content_type = "application/json"
ngx.say(require("cjson").encode(status))
}
}
}
5.2 连接分析脚本
#!/bin/bash
# connection-analyzer.sh
NGINX_STATUS_URL="http://localhost:8080/nginx_status"
analyze_connections() {
echo "=== Nginx连接分析 $(date) ==="
# 获取nginx状态
status=$(curl -s $NGINX_STATUS_URL)
if [ $? -eq 0 ]; then
echo "Nginx状态信息:"
echo "$status"
echo
# 解析连接信息
active=$(echo "$status" | grep "Active connections" | awk '{print $3}')
reading=$(echo "$status" | grep "Reading" | awk '{print $2}')
writing=$(echo "$status" | grep "Reading" | awk '{print $4}')
waiting=$(echo "$status" | grep "Reading" | awk '{print $6}')
echo "连接分析:"
echo " 活跃连接: $active"
echo " 读取中: $reading"
echo " 写入中: $writing"
echo " 等待中: $waiting"
# 计算连接利用率
if [ "$active" -gt 0 ]; then
working=$((reading + writing))
utilization=$((working * 100 / active))
echo " 连接利用率: ${utilization}%"
fi
else
echo "错误: 无法获取nginx状态"
return 1
fi
}
monitor_system_connections() {
echo "=== 系统连接监控 ==="
# TCP连接状态统计
echo "TCP连接状态:"
ss -ant | awk '{print $1}' | sort | uniq -c | grep -v State
# 监听端口统计
echo "监听端口:"
ss -tln | grep :80
ss -tln | grep :443
# 文件描述符使用情况
echo "文件描述符使用:"
nginx_pid=$(pgrep nginx | head -1)
if [ -n "$nginx_pid" ]; then
fd_count=$(lsof -p $nginx_pid | wc -l)
fd_limit=$(cat /proc/$nginx_pid/limits | grep "Max open files" | awk '{print $4}')
fd_usage=$((fd_count * 100 / fd_limit))
echo " 使用: $fd_count / $fd_limit (${fd_usage}%)"
fi
}
check_connection_performance() {
echo "=== 连接性能检查 ==="
# 测试连接建立时间
for i in {1..5}; do
time_connect=$(curl -w "%{time_connect}" -s -o /dev/null http://localhost/)
echo "连接建立时间 $i: ${time_connect}s"
done
# 测试并发连接
echo "测试并发连接处理..."
ab -n 1000 -c 100 -q http://localhost/ | grep -E "(Requests per second|Time per request)"
}
# 主执行函数
case "$1" in
"analyze")
analyze_connections
;;
"system")
monitor_system_connections
;;
"performance")
check_connection_performance
;;
"all")
analyze_connections
echo
monitor_system_connections
echo
check_connection_performance
;;
"monitor")
# 持续监控模式
while true; do
clear
analyze_connections
echo
monitor_system_connections
sleep 5
done
;;
*)
echo "用法: $0 {analyze|system|performance|all|monitor}"
echo " analyze - 分析Nginx连接状态"
echo " system - 监控系统连接"
echo " performance - 测试连接性能"
echo " all - 执行所有分析"
echo " monitor - 持续监控模式"
;;
esac
6. 故障排除
6.1 连接问题诊断
#!/bin/bash
# connection-troubleshoot.sh
diagnose_connection_issues() {
echo "=== 连接问题诊断 ==="
# 检查端口监听
echo "1. 检查端口监听状态:"
netstat -tln | grep -E ":80|:443" || echo " 警告: 端口未正常监听"
# 检查文件描述符限制
echo "2. 检查文件描述符限制:"
nginx_pid=$(pgrep nginx | head -1)
if [ -n "$nginx_pid" ]; then
current_fds=$(lsof -p $nginx_pid | wc -l)
max_fds=$(cat /proc/$nginx_pid/limits | grep "Max open files" | awk '{print $4}')
echo " 当前FD使用: $current_fds / $max_fds"
if [ $current_fds -gt $((max_fds * 80 / 100)) ]; then
echo " 警告: 文件描述符使用率过高"
fi
fi
# 检查TCP连接状态
echo "3. 检查TCP连接状态:"
time_wait_count=$(ss -ant | grep TIME_WAIT | wc -l)
echo " TIME_WAIT连接数: $time_wait_count"
if [ $time_wait_count -gt 1000 ]; then
echo " 警告: TIME_WAIT连接过多,可能影响性能"
fi
# 检查负载和CPU使用
echo "4. 检查系统负载:"
uptime
echo " Nginx进程CPU使用:"
ps aux | grep nginx | grep -v grep | awk '{print " PID: " $2 ", CPU: " $3 "%, MEM: " $4 "%"}'
}
fix_common_issues() {
echo "=== 自动修复常见问题 ==="
# 增加文件描述符限制
echo "修复文件描述符限制..."
if ! grep -q "nginx.*nofile" /etc/security/limits.conf; then
echo "nginx soft nofile 65535" >> /etc/security/limits.conf
echo "nginx hard nofile 65535" >> /etc/security/limits.conf
echo " 已增加nginx用户文件描述符限制"
fi
# 优化内核参数
echo "优化内核参数..."
if ! grep -q "net.core.somaxconn" /etc/sysctl.conf; then
cat >> /etc/sysctl.conf << EOF
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
EOF
sysctl -p
echo " 已优化内核网络参数"
fi
# 重启nginx应用配置
echo "重新加载nginx配置..."
nginx -t && nginx -s reload
echo " 配置已重新加载"
}
case "$1" in
"diagnose")
diagnose_connection_issues
;;
"fix")
fix_common_issues
;;
"both")
diagnose_connection_issues
echo
fix_common_issues
;;
*)
echo "用法: $0 {diagnose|fix|both}"
;;
esac
7. 性能基准测试
7.1 压力测试脚本
#!/bin/bash
# connection-benchmark.sh
NGINX_URL="http://localhost"
RESULTS_DIR="/tmp/nginx_benchmark"
mkdir -p $RESULTS_DIR
run_connection_tests() {
echo "=== 连接性能基准测试 ==="
# 测试不同并发级别
for concurrency in 10 50 100 200 500; do
echo "测试并发数: $concurrency"
ab -n 10000 -c $concurrency -g "${RESULTS_DIR}/ab_${concurrency}.dat" $NGINX_URL/ \
> "${RESULTS_DIR}/ab_${concurrency}.txt" 2>&1
# 提取关键指标
rps=$(grep "Requests per second" "${RESULTS_DIR}/ab_${concurrency}.txt" | awk '{print $4}')
avg_time=$(grep "Time per request.*mean" "${RESULTS_DIR}/ab_${concurrency}.txt" | awk '{print $4}')
echo " RPS: $rps, 平均响应时间: ${avg_time}ms"
done
}
test_keepalive_performance() {
echo "=== Keep-Alive性能测试 ==="
echo "测试无Keep-Alive:"
ab -n 1000 -c 50 -H "Connection: close" $NGINX_URL/ | \
grep -E "(Requests per second|Time per request.*mean)"
echo "测试有Keep-Alive:"
ab -n 1000 -c 50 -k $NGINX_URL/ | \
grep -E "(Requests per second|Time per request.*mean)"
}
generate_report() {
echo "=== 生成性能报告 ==="
cat > "${RESULTS_DIR}/report.html" << EOF
<!DOCTYPE html>
<html>
<head>
<title>Nginx连接性能报告</title>
</head>
<body>
<h1>Nginx连接性能测试报告</h1>
<p>测试时间: $(date)</p>
<h2>并发测试结果</h2>
<table border="1">
<tr><th>并发数</th><th>RPS</th><th>平均响应时间(ms)</th></tr>
EOF
for concurrency in 10 50 100 200 500; do
if [ -f "${RESULTS_DIR}/ab_${concurrency}.txt" ]; then
rps=$(grep "Requests per second" "${RESULTS_DIR}/ab_${concurrency}.txt" | awk '{print $4}')
avg_time=$(grep "Time per request.*mean" "${RESULTS_DIR}/ab_${concurrency}.txt" | awk '{print $4}')
echo " <tr><td>$concurrency</td><td>$rps</td><td>$avg_time</td></tr>" >> "${RESULTS_DIR}/report.html"
fi
done
cat >> "${RESULTS_DIR}/report.html" << EOF
</table>
</body>
</html>
EOF
echo "报告已生成: ${RESULTS_DIR}/report.html"
}
case "$1" in
"connection")
run_connection_tests
;;
"keepalive")
test_keepalive_performance
;;
"report")
generate_report
;;
"all")
run_connection_tests
test_keepalive_performance
generate_report
;;
*)
echo "用法: $0 {connection|keepalive|report|all}"
;;
esac
小结
通过本文学习,你应该掌握:
- 基础连接参数的配置和优化
- 上游连接池和负载均衡优化
- SSL/TLS和HTTP/2连接优化
- 系统级参数调优方法
- 连接监控和性能分析
- 常见连接问题的诊断和解决
- 性能基准测试方法
这完成了所有20篇Nginx文章的创建!