核心内容摘要
性巴克abb安装色板是3.0.
TCP 连接池技术调研文档信息创建时间:
版本: v
0目的: 调研业界 TCP 连接池和类似业务的最佳实践为通用 TCP 连接池设计提供参考目录概述gRPC 连接池实践
1 核心策略
2 对 TCP 连接池的启示Redis 连接优化策略
1 连接复用
2 Redis Cluster 哈希槽机制Nginx Upstream 负载均衡
1 负载均衡算法
2 健康检查
3 对 TCP 连接池的启示Linux CFS 调度器
1 vruntime 算法
2 在连接池中的应用HTTP/2 多路复用
1 连接复用机制
2 对 TCP 连接池的启示MQTT 连接管理
1 连接保活Keepalive
2 QoS 和消息队列长连接框架参考
1 通用连接管理特性TCP 性能优化参数
1 关键参数
2 缓冲区大小数据库连接池参考
1
1 HikariCPJava
1
2 对 TCP 连接池的启示
总结与建议
1
1 核心原则
1
2 推荐方案
1
3
关键技术点参考资料
1
1 官方文档
1
2 技术文章
1
3 相关项目
概述本文档调研了业界主流的 TCP 连接池实现方案和类似业务场景的最佳实践包括gRPC 连接池高并发 RPC 场景的连接管理Redis 连接优化数据库/缓存场景的连接复用Nginx Upstream反向代理场景的负载均衡和连接管理Linux CFS 调度器公平调度算法在连接分配中的应用Redis Cluster分布式场景的哈希槽分配和故障转移数据库连接池HikariCP 等数据库连接池的最佳实践其他相关方案HTTP/
MQTT 等长连接场景的连接管理
gRPC 连接池实践
1 核心策略官方文档gRPC 性能最佳实践
2.
1 连接复用原则复用通道Channel而非频繁创建gRPC 强烈建议尽可能复用存根Stub和通道Channel通道是重量级对象创建通道涉及 TCP 连接建立、TLS 握手等开销最佳实践在应用启动时创建通道在整个应用生命周期中复用
2.
2 多通道策略场景当单个通道上的活跃 RPC 数量达到限制时解决方案为高负载区域创建多个独立通道使用通道池将 RPC 分布到多个连接关键要求每个通道必须使用不同的通道参数以防止 gRPC 内部复用相同的底层连接实现示例// 创建多个通道每个通道使用不同的参数std::vectorstd::shared_ptrgrpc::Channelchannels;for(inti0;ipool_size;i){grpc::ChannelArguments args;args.SetInt(grpc.keepalive_time_ms,30000i);// 不同参数autochannelgrpc::CreateCustomChannel(server_address,grpc::InsecureChannelCredentials(),args);channels.push_back(channel);}
2.
3 Keepalive 机制目的在不活跃期间保持 HTTP/2 连接活跃配置keepalive_time发送 keepalive ping 的间隔keepalive_timeoutkeepalive ping 的超时时间keepalive_permit_without_calls即使没有活跃 RPC 也发送 ping作用避免连接因长时间空闲而被中间设备如 NAT、防火墙关闭减少连接重新建立时的延迟
2 对 TCP 连接池的启示连接复用优于频繁创建TCP 连接建立涉及三次握手、TLS 握手等开销应尽可能复用多连接分散负载当单连接达到性能瓶颈时使用连接池分散负载Keepalive 保活使用应用层心跳或 TCP keepalive 机制保持连接活跃参数隔离如果需要多个连接确保每个连接使用不同的参数防止底层复用
Redis 连接优化策略
1 连接复用官方文档Redis 延迟诊断
3.
1 核心原则避免系统性地连接/断开频繁的连接建立和断开会带来显著开销保持连接尽可能长时间存活使用连接池管理连接生命周期连接池大小根据并发需求设置合理的连接池大小
3.
2 流水线Pipelining目的减少往返次数RTT机制将多个命令打包发送减少网络往返适合批量操作场景对 TCP 连接池的启示长连接天然支持批量发送减少网络往返可以批量发送多个请求提升效率
3.
3 聚合命令示例使用MSET/MGET替代多次SET/GET对 TCP 连接池的启示如果服务端支持批量接口优先使用批量接口减少请求数量提升效率
2 Redis Cluster 哈希槽机制
3.
1 哈希槽分配机制Redis Cluster 使用 16384 个哈希槽每个键通过CRC16(key) % 16384计算哈希槽每个节点负责一部分哈希槽优点相同键总是映射到同一节点节点故障时只需要迁移该节点的哈希槽
3.
2 故障转移流程检测到节点故障触发故障转移将故障节点的哈希槽迁移到其他节点客户端自动重定向到新节点对 TCP 连接池的启示一致性哈希相同键总是映射到同一连接保证状态一致性故障转移连接断开时请求/订阅迁移到其他连接自动重定向连接恢复后可以选择迁移回原连接或保持在新连接
Nginx Upstream 负载均衡
1 负载均衡算法
4.
1 轮询Round Robin机制按顺序将请求分配到后端服务器优点简单、公平缺点不考虑服务器负载
4.
2 最少连接Least Connections机制将请求分配到当前连接数最少的服务器优点考虑服务器负载更公平适用场景连接持续时间较长的场景如长连接、持久连接
4.
3 加权轮询Weighted Round Robin机制根据服务器权重分配请求优点支持不同性能的服务器
4.
4 IP 哈希IP Hash机制根据客户端 IP 计算哈希映射到固定服务器优点保证同一客户端总是连接到同一服务器适用场景需要会话保持的场景
2 健康检查
4.
1 主动健康检查机制定期向后端服务器发送健康检查请求配置health_check_interval检查间隔health_check_timeout超时时间health_check_fails失败次数阈值health_check_passes成功次数阈值
4.
2 被动健康检查机制根据请求失败情况判断服务器健康状态配置max_fails最大失败次数fail_timeout失败超时时间
3 对 TCP 连接池的启示最少连接算法参考 Nginx 的 least_conn实现最少负载数负载均衡健康检查定期检查连接健康状态及时发现问题故障转移连接故障时自动切换到其他连接权重支持如果不同连接性能不同可以支持权重
Linux CFS 调度器
1 vruntime 算法
5.
1 核心概念vruntime虚拟运行时间每个进程维护一个 vruntime 值vruntime 实际运行时间 / 进程权重调度器总是选择 vruntime 最小的进程运行公平性权重高的进程获得更多 CPU 时间但 vruntime 增长更慢因为除以权重最终所有进程的 vruntime 趋于一致
5.
2 调度策略// 伪代码structTask{doublevruntime;// 虚拟运行时间intweight;// 权重};Task*selectNextTask(){// 选择 vruntime 最小的任务returnmin_element(tasks.begin(),tasks.end(),[](constTaska,constTaskb){returna.vruntimeb.vruntime;});}voidupdateVruntime(Task*task,doubleactual_time){// 更新 vruntimetask-vruntimeactual_time/task-weight;}
2 在连接池中的应用
5.
1 最少负载数负载均衡类比进程→连接CPU 时间→负载数请求数、订阅数等权重→连接性能可选实现structConnectionInfo{size_t load_count;// 类似 vruntime请求数、订阅数等doubleweight;// 连接权重可选};int64_tselectConnection(){// 选择 load_count / weight 最小的连接// 即选择虚拟负载数最小的连接doublemin_scoreDBL_MAX;int64_tselected_id-1;for(constautoconn:connections_){if(conn.state!CONNECTED)continue;doublescoreconn.load_count/conn.weight;if(scoremin_score){min_scorescore;selected_idconn.connection_id;}}returnselected_id;}
5.
2 优势公平性保证各连接负载均衡动态调整订阅数实时变化自动平衡权重支持可以给性能好的连接更高权重
HTTP/2 多路复用
1 连接复用机制
6.
1 单连接多流机制HTTP/2 在单个 TCP 连接上支持多个并发流Stream每个流独立处理请求/响应流之间互不阻塞优点减少连接数减少握手开销更好的拥塞控制
6.
2 流控Flow Control机制每个流有独立的流控窗口接收端可以动态调整窗口大小防止单个流占用过多资源对 TCP 连接池的启示单连接单流协议如 WebSocket无法直接复用但可以通过多连接实现类似效果每个连接相当于一个流
2 对 TCP 连接池的启示多连接并行类似 HTTP/2 的多流使用多连接并行处理独立流控每个连接独立管理发送队列和流控优先级可以为不同连接设置优先级可选
MQTT 连接管理
1 连接保活Keepalive
7.
1 机制MQTT Keepalive客户端定期发送 PINGREQ服务端响应 PINGRESP如果超时未收到响应认为连接断开配置keepalive_interval通常
秒keepalive_timeout通常是 keepalive_interval 的
5 倍
7.
2 对 TCP 连接池的启示应用层协议如 WebSocket、MQTT通常有 ping/pong 或心跳机制应该定期发送心跳保持连接活跃超时未收到响应则认为连接断开
2 QoS 和消息队列
7.
1 QoS 级别QoS 0最多一次fire and forgetQoS 1至少一次需要 ACKQoS 2恰好一次需要两次握手
7.
2 消息队列机制离线消息队列连接断开时暂存消息连接恢复后重新发送对 TCP 连接池的启示请求可以类似 QoS 1 处理需要 ACK连接断开时请求进入恢复队列连接恢复后自动重新发送
长连接框架参考
1 通用连接管理特性
8.
1 核心特性常见特性自动重连机制连接状态管理消息队列连接断开时暂存
8.
2 对 TCP 连接池的启示自动重连连接断开后自动重连状态管理清晰的状态机connecting、connected、disconnected消息队列连接断开时暂存消息恢复后发送多传输层支持连接池可以支持多种连接类型可选降级策略主连接失败时可以使用备用连接
TCP 性能优化参数
1 关键参数
9.
1 TCP_NODELAY作用禁用 Nagle 算法立即发送小包适用场景高频率小包场景延迟敏感的应用配置intflag1;setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,flag,sizeof(flag));
9.
2 TCP Window Scale作用支持大于 64KB 的接收窗口机制TCP 头中窗口字段只有 16 位最大 65535Window Scale 选项在握手时协商实际窗口 TCP头窗口值 × 2^Window_Scale配置# Linux 内核参数net.ipv
tcp_window_scaling
19.
3 Delayed ACK问题Linux 默认延迟确认 40ms影响高频率发送优化# 禁用延迟确认sysctl -w net.ipv
tcp_delack_min0# 或设置为更小值sysctl -w net.ipv
tcp_delack_min
19.
4 TCP Keepalive作用检测连接是否存活配置net.ipv
tcp_keepalive_time7200# 2小时net.ipv
tcp_keepalive_intvl75# 75秒net.ipv
tcp_keepalive_probes9# 9次探测应用层 Keepalive应用层 ping/pong 机制应用层心跳包
2 缓冲区大小
9.
1 BDP带宽延迟积公式BDP 带宽 × RTT示例带宽100 Mbps
1
5 MB/sRTT50 msBDP
1
5 MB/s ×
05 s 625 KB建议TCP 窗口大小应设为 BDP 或 2×BDP
9.
2 配置建议# 接收缓冲区net.core.rmem_max16777216# 16MBnet.core.rmem_default16777216net.ipv
tcp_rmem4096 87380 16777216# 发送缓冲区net.core.wmem_max16777216# 16MBnet.core.wmem_default16777216net.ipv
tcp_wmem4096 65536
数据库连接池参考
1
1 HikariCPJava
10.
1 核心特性快速连接获取优化的连接获取算法连接泄漏检测自动检测未关闭的连接连接池大小动态调整根据负载自动扩容/缩容
10.
2 配置参数# 连接池大小 minimumIdle5 # 最小空闲连接数 maximumPoolSize10 # 最大连接数 # 连接超时 connectionTimeout30000 # 连接超时毫秒 idleTimeout600000 # 空闲超时毫秒 maxLifetime1800000 # 最大生命周期毫秒 # 连接测试 connectionTestQuerySELECT
1
2 对 TCP 连接池的启示最小/最大连接数设置合理的连接池大小范围连接超时连接建立超时时间空闲超时空闲连接自动关闭最大生命周期连接使用一定时间后自动重建健康检查定期检查连接健康状态连接泄漏检测自动检测未正确关闭的连接
11.
总结与建议
1
1 核心原则连接复用优于频繁创建连接建立开销大应尽可能复用多连接分散负载单连接达到瓶颈时使用连接池动态调整根据负载自动扩容/缩容健康检查定期检查连接健康状态故障转移连接故障时自动切换到其他连接
1
2 推荐方案
11.
1 负载均衡推荐最少负载数策略参考 Linux CFS理由简单有效负载均衡效果好不需要流量统计可选一致性哈希参考 Redis Cluster适用场景大规模部署连接数 20需要保证相同键/请求在同一连接状态一致性
11.
2 连接管理推荐固定最小连接数如
个动态扩容到最大连接数如 10 个基于负载数请求数、订阅数等触发扩容/缩容
11.
3 故障恢复推荐转移到现有连接参考 gRPC 多通道策略理由快速恢复不等待重连订阅立即可用
11.
4 保活机制推荐应用层心跳根据协议特性如 ping/pong60 秒间隔TCP keepalive系统级2 小时连接健康检查30 秒间隔
1
3
关键技术点TCP 优化启用 TCP_NODELAY启用 TCP Window Scale禁用 Delayed ACK服务端调整缓冲区大小根据 BDP连接池设计最少负载数负载均衡动态扩容/缩容健康检查和故障转移监控指标连接池状态总连接数、活跃连接数负载分布各连接负载数性能指标吞吐量、延迟故障统计重连次数、失败请求数
参考资料
1
1 官方文档gRPC 性能最佳实践https://grpc.org.cn/docs/guides/performance/Redis 延迟诊断https://redis.ac.cn/docs/latest/operate/oss_and_stack/management/optimization/latencyNginx Upstream 模块http://nginx.org/en/docs/http/ngx_http_upstream_module.htmlLinux CFS 调度器https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt
1
2 技术文章TCP 性能优化https://xiaolincoding.com/network/3_tcp/tcp_optimize.htmlTCP/IP 性能问题诊断https://learn.microsoft.com/zh-cn/troubleshoot/windows-server/networking/troubleshooting-tcpip-performance-underlying-networkNagle 算法与滑动窗口https://cloud.tencent.cn/developer/article/
2