4.9.6 服务端与中间件网络优化实践
面向服务端与中间件的网络优化实践应从连接模型、传输协议、队列与缓存、超时与重试、负载均衡与高可用等维度系统梳理,并以真实业务流量为基准进行参数验证。优先明确业务特征(长连接/短连接、突发/均匀、读多写多、同步/异步)与链路拓扑(客户端—LB—应用—中间件—存储),避免单点优化引发级联问题。
原理草图:典型链路与关注点
通用优化原则(含命令示例)
- 连接数与FD:评估峰值并预留裕度,合理设置进程FD上限、连接池大小与backlog,避免accept队列溢出。
# 查看当前FD与限制
ulimit -n
cat /proc/sys/fs/file-max
# 临时提升当前shell FD
ulimit -n 200000
# 内核/系统级(永久)配置
cat >/etc/sysctl.d/99-net-tuning.conf <<'EOF'
fs.file-max = 500000
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 100000
EOF
sysctl -p /etc/sysctl.d/99-net-tuning.conf
# 解释
# somaxconn: listen队列上限,避免大量并发时accept队列溢出
# netdev_max_backlog: 内核接收队列长度,防丢包
- 超时与重试:客户端与服务端超时要分层(连接、读、写、空闲),重试需带退避与幂等保护。
# 用curl模拟连接与读超时
curl -m 2 --connect-timeout 1 http://127.0.0.1:8080/health
# 解释
# --connect-timeout: 连接阶段超时
# -m/--max-time: 总超时
- 监控与抓包:以RTT、重传率、队列长度、RST/FIN比例、应用P99延迟为核心指标。
# RTT与丢包
ping -c 20 -i 0.2 10.0.0.10
# 连接与队列
ss -s
ss -lntp | head
# 抓包看重传与RST
tcpdump -i eth0 'tcp and (tcp[tcpflags] & (tcp-rst) != 0)' -nn
Nginx/Web服务(示例、安装、排错、练习)#
原理要点:事件驱动+连接复用。参数关注worker_*、keepalive、sendfile、proxy_*。
安装示例(RHEL系)
yum install -y nginx
systemctl enable --now nginx
nginx -V
配置示例(/etc/nginx/nginx.conf)
worker_processes auto;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30s;
keepalive_requests 1000;
server {
listen 80 reuseport;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_connect_timeout 1s;
proxy_read_timeout 5s;
proxy_send_timeout 5s;
client_max_body_size 10m;
}
}
}
验证命令
nginx -t
systemctl reload nginx
ss -lntp | grep nginx
排错清单
- 502/504:检查proxy_read_timeout与后端响应时间
- 大量TIME_WAIT:增大keepalive_timeout或启用连接复用
- 连接拒绝:确认worker_connections与ulimit -n
练习
- 将keepalive_timeout从30s改为5s,观察TIME_WAIT数量变化:
ss -ant state time-wait | wc -l
MySQL(示例、安装、排错、练习)#
原理要点:连接池控制+线程与网络超时协调。
安装示例(RHEL系)
yum install -y mysql-server
systemctl enable --now mysqld
mysql -uroot -e "select version();"
配置示例(/etc/my.cnf)
[mysqld]
max_connections=2000
net_read_timeout=10
net_write_timeout=10
max_allowed_packet=64M
验证命令
mysql -uroot -e "show variables like 'max_connections';"
mysql -uroot -e "show status like 'Threads_connected';"
排错清单
- Too many connections:调整连接池上限与max_connections
- 大包超时:增大max_allowed_packet和net_read_timeout
- 复制延迟:查看Seconds_Behind_Master与链路重传
练习
# 模拟多连接
for i in {1..200};do mysql -uroot -e "select 1" & done
Redis(示例、安装、排错、练习)#
原理要点:单线程高并发依赖网络与连接队列。
安装示例
yum install -y redis
systemctl enable --now redis
redis-cli ping
配置示例(/etc/redis.conf)
tcp-backlog 65535
timeout 0
repl-timeout 60
repl-backlog-size 128mb
验证命令
redis-cli info stats | egrep 'rejected_connections|total_connections_received'
排错清单
- 连接拒绝:检查tcp-backlog与somaxconn
- 延迟飙升:检查慢命令slowlog与pipeline是否开启
练习
# Pipeline压力测试
redis-cli --pipe <<'EOF'
SET k1 v1
SET k2 v2
GET k1
EOF
Kafka(示例、安装、排错、练习)#
原理要点:网络线程+IO线程分离,批量与压缩提升吞吐。
安装示例(使用二进制)
tar -xf kafka_2.13-3.6.0.tgz -C /opt
/opt/kafka_2.13-3.6.0/bin/kafka-storage.sh random-uuid
配置示例(/opt/kafka_2.13-3.6.0/config/server.properties)
num.network.threads=8
num.io.threads=16
socket.request.max.bytes=104857600
验证命令
# 生产与消费
/opt/kafka_2.13-3.6.0/bin/kafka-topics.sh --create \
--bootstrap-server 127.0.0.1:9092 --topic t1 --partitions 3 --replication-factor 1
排错清单
- RequestQueueTime高:增加num.network.threads
- 网络延迟高:开启压缩compression.type=zstd
练习
/opt/kafka_2.13-3.6.0/bin/kafka-producer-perf-test.sh \
--topic t1 --num-records 100000 --record-size 1000 --throughput 5000 \
--producer-props bootstrap.servers=127.0.0.1:9092 linger.ms=5 batch.size=65536
ZooKeeper / Nacos(示例、安装、排错、练习)#
原理要点:长连接心跳,超时参数决定会话稳定性。
ZK安装示例
tar -xf apache-zookeeper-3.8.4-bin.tar.gz -C /opt
cp /opt/apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg /opt/apache-zookeeper-3.8.4-bin/conf/zoo.cfg
/opt/apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
ZK配置示例(zoo.cfg)
tickTime=2000
initLimit=10
syncLimit=5
maxClientCnxns=200
验证命令
/opt/apache-zookeeper-3.8.4-bin/bin/zkCli.sh -server 127.0.0.1:2181 ls /
排错清单
- 会话频繁断开:增大sessionTimeout或tickTime
- 客户端过多:提高maxClientCnxns并用连接池
练习
- 用脚本循环创建会话,观察连接数变化:
for i in {1..50};do echo "ls /" | /opt/apache-zookeeper-3.8.4-bin/bin/zkCli.sh -server 127.0.0.1:2181 >/dev/null;done
HAProxy / Keepalived(示例、安装、排错、练习)#
原理要点:L4/L7负载、队列与健康检查;VRRP心跳切换。
HAProxy安装与配置
yum install -y haproxy
cat >/etc/haproxy/haproxy.cfg <<'EOF'
global
maxconn 20000
defaults
mode http
timeout connect 2s
timeout client 10s
timeout server 10s
frontend fe_http
bind *:80
default_backend be_app
backend be_app
balance roundrobin
server s1 127.0.0.1:8080 check
server s2 127.0.0.1:8081 check
EOF
systemctl enable --now haproxy
Keepalived示例(/etc/keepalived/keepalived.conf)
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
virtual_ipaddress {
10.0.0.100/24
}
}
排错清单
- 后端排队:观察qcur/qtime并增大maxconn
- 频繁切换:增大advert_int或禁用抢占
练习
echo "show stat" | socat stdio /run/haproxy/admin.sock | head
ProxySQL(示例、安装、排错、练习)#
原理要点:连接复用+读写分离,减少后端连接压力。
安装示例
yum install -y proxysql
systemctl enable --now proxysql
配置示例(SQL管理口)
-- 连接管理端口
mysql -u admin -padmin -h 127.0.0.1 -P 6032
-- 设置后端连接与线程
UPDATE global_variables SET variable_value='4' WHERE variable_name='mysql-threads';
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-max_connections';
LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;
排错清单
- 连接耗尽:增加mysql-max_connections与后端连接池
- 跨机房高RTT:调整路由规则避免跨地域读
练习
- 写入一条路由规则并验证:
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup) VALUES (1,1,'^SELECT',20);
LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
Docker / Kubernetes(示例、安装、排错、练习)#
原理要点:CNI选择、NAT/conntrack表、跨节点通信减少转发层级。
安装示例(Docker)
yum install -y docker
systemctl enable --now docker
docker info | egrep 'Server Version|Cgroup'
conntrack调整示例
sysctl -w net.netfilter.nf_conntrack_max=262144
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=600
K8s排错命令
# 查看Pod网络丢包/延迟(需安装工具)
kubectl exec -it pod-name -- sh -c "ping -c 10 10.244.0.1"
# 查看conntrack占用
conntrack -C
练习
- 部署两个Pod并测试跨节点RTT,记录RTT差异并分析CNI模式。
Prometheus / Jenkins(示例、安装、排错、练习)#
Prometheus安装与配置
tar -xf prometheus-2.48.0.linux-amd64.tar.gz -C /opt
cat >/opt/prometheus-2.48.0.linux-amd64/prometheus.yml <<'EOF'
global:
scrape_interval: 15s
scrape_timeout: 5s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
EOF
Jenkins网络参数示例
# 启动时设置HTTP端口与代理超时(示例)
java -jar jenkins.war --httpPort=8080 --handlerCountMax=100
排错清单
- Prometheus抓取超时:调整scrape_timeout与并发
- Jenkins构建失败:检查制品仓库连接与DNS解析
练习
- 将scrape_interval改为5s,观察CPU与网络影响。
问题定位要点(含示例)
# 高延迟伴随重传
ss -ti dst 10.0.0.10:3306 | egrep 'retrans|rtt'
# 连接拒绝或队列满
ss -lntp | egrep 'Recv-Q|Send-Q'
综合排错流程
1. 先确认链路与MTU:ping -M do -s 1472 <IP>
2. 看队列与重传:ss -s、tcpdump
3. 对比应用P99延迟与系统级指标
4. 小步修改参数并回归压测
综合练习(最小化验证)
- 目标:Nginx反代到应用端口,模拟200并发访问,观察TIME_WAIT。
# 压测
ab -n 10000 -c 200 http://127.0.0.1/
# 观察TIME_WAIT
ss -ant state time-wait | wc -l
- 记录调整前后
keepalive_timeout对TIME_WAIT的影响,并输出结论。