Netty 百万长连接推送网关生产实战
引言企微推送、电商秒杀通知、IoT 指令下发……这些场景都有一个共同挑战如何在单台机器上维持几十万甚至百万级长连接并在下游抖动时保证系统不雪崩。本篇文章基于 Netty 构建一套生产级推送网关从连接治理到可观测性全链路展开。指标数值说明单机连接数1.2M16C32G 云主机内核参数调优后实测消息峰值 QPS80W批量合并 零拷贝推送P99 推送延迟 8ms心跳 写缓冲区水位控制GC 停顿 10ms对象池 堆外内存 ZGC01 架构全景四层网关模型生产级推送网关不是简单的 WebSocket Server。它需要处理接入层负载均衡、连接状态管理、消息路由、下游保护四个核心职责。───────────────────────────────────────────────────────────────── 接入层iOS/Android/Web/小程序 → HAProxy → Spring Cloud Gateway ───────────────────────────────────────────────────────────────── 连接层ChannelGroup ↔ UserId→Channel 本地索引 ↔ IdleStateHandler ───────────────────────────────────────────────────────────────── 路由层Kafka push.topic → Consumer Pool → 本地路由表 / 广播 ───────────────────────────────────────────────────────────────── 保护层写水位 令牌桶限流 Resilience4j 熔断 Prometheus ─────────────────────────────────────────────────────────────────关键设计决策有状态服务长连接必须落在固定 Netty 节点L4 负载均衡采用源地址哈希避免七层再路由。本地索引优先用户在线状态先查本地ConcurrentHashMap未命中再回查 Redis降低 90% 以上远程调用。广播转局部全量推送通过 Kafka 分片消费只推送本节点挂载的连接避免跨节点 RPC 风暴。02 连接治理百万连接的内存与线程模型Netty 的线程模型是性能基石。生产环境使用EpollEventLoopGroupLinux并设置合理的SO_BACKLOG、TCP_NODELAY、SO_KEEPALIVE。publicclassPushGatewayServerimplementsLifecycle{privatefinalEventLoopGroupbossGroupnewEpollEventLoopGroup(1);privatefinalEventLoopGroupworkerGroupnewEpollEventLoopGroup(0,newDefaultThreadFactory(netty-worker));publicvoidstart(intport)throwsInterruptedException{ServerBootstrapbnewServerBootstrap();b.group(bossGroup,workerGroup).channel(EpollServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,8192).option(ChannelOption.SO_REUSEADDR,true).childOption(ChannelOption.TCP_NODELAY,true).childOption(ChannelOption.SO_KEEPALIVE,true).childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT).childHandler(newChannelInitializerSocketChannel(){OverrideprotectedvoidinitChannel(SocketChannelch){ch.config().setWriteBufferWaterMark(newWriteBufferWaterMark(32*1024,256*1024));ch.pipeline().addLast(idle,newIdleStateHandler(90,30,0)).addLast(codec,newPushProtocolCodec()).addLast(auth,newAuthHandshakeHandler(jwtVerifier,sessionStore)).addLast(biz,newPushBusinessHandler(connectionManager,pushRouter));}});b.bind(port).sync();}}连接管理器需要解决三个问题线程安全、快速查找、优雅下线。采用用户 ID 与 Channel 的多级索引publicclassConnectionManager{// userId - Channel 主索引privatefinalConcurrentHashMapString,ChanneluserChannelMapnewConcurrentHashMap();// ChannelId - userId 反向索引用于断线时清理privatefinalConcurrentHashMapString,StringchannelUserMapnewConcurrentHashMap();publicvoidbind(StringuserId,Channelchannel){channel.attr(Attributes.USER_ID).set(userId);ChannelprevuserChannelMap.put(userId,channel);if(prev!nullprev.isActive()){// 同一用户新登录踢掉旧连接prev.writeAndFlush(newKickoutMessage(new_login)).addListener(ChannelFutureListener.CLOSE);}channelUserMap.put(channel.id().asShortText(),userId);Metrics.CONNECTIONS.increment();}publicvoidunbind(Channelchannel){StringuserIdchannel.attr(Attributes.USER_ID).getAndSet(null);if(userId!null){userChannelMap.remove(userId,channel);channelUserMap.remove(channel.id().asShortText());Metrics.CONNECTIONS.decrement();}}}03 背压与限流防止客户端拖垮整个集群推送网关最常见的故障模式是下游某个客户端接收极慢TCP 发送缓冲区堆积最终把服务内存撑爆。生产方案需要业务层背压 令牌桶限流 慢连接熔断三位一体。publicclassBackPressurePushHandlerextendsChannelOutboundHandlerAdapter{privatefinalSemaphoreglobalInflightnewSemaphore(500_000);privatefinalRateLimiterglobalRateLimiterRateLimiter.create(800_000.0);Overridepublicvoidwrite(ChannelHandlerContextctx,Objectmsg,ChannelPromisepromise){Channelchctx.channel();// 1. 全局 QPS 限流保证 CPU 不跑满if(!globalRateLimiter.tryAcquire(1,TimeUnit.MILLISECONDS)){Metrics.RATE_LIMITED.increment();ReferenceCountUtil.release(msg);promise.setFailure(newPushException(global rate limit));return;}// 2. 写缓冲区水位背压单个 channel 排队超过阈值直接丢弃if(!ch.isWritable()){Metrics.BACK_PRESSURE_DROP.increment();ReferenceCountUtil.release(msg);promise.setFailure(newPushException(channel not writable));return;}// 3. 全局在途消息数限制防止内存无限增长if(!globalInflight.tryAcquire()){Metrics.INFLIGHT_REJECT.increment();ReferenceCountUtil.release(msg);promise.setFailure(newPushException(inflight overflow));return;}ctx.write(msg,promise).addListener(f-globalInflight.release());}}三个层级的保护全局 QPS 限流基于 Guava RateLimiter保护 Netty Worker 线程不被打满。写缓冲区背压isWritable()判断的是 Netty 写水位低层且高效。全局在途计数通过 Semaphore 限制未确认的消息总量避免瞬时洪峰导致 OOM。04 熔断降级下游抖动时的自愈机制推送网关对接的业务系统如企微回调、订单中心偶尔会出现超时或错误率飙升。如果网关无脑重试会把故障放大。使用 Resilience4j 对按用户维度聚合后的批量推送接口做熔断并配合降级策略。publicclassProtectedPushService{privatefinalCircuitBreakerRegistryregistry;privatefinalPushMetricsmetrics;publicMonoVoidpushBatch(StringbizType,ListPushMessagemessages){CircuitBreakercbregistry.circuitBreaker(bizType,default);returnMono.fromCallable(()-doPushBatch(messages)).transformDeferred(CircuitBreakerOperator.of(cb)).doOnSuccess(v-metrics.recordSuccess(bizType,messages.size())).doOnError(e-metrics.recordFailure(bizType,e.getClass().getSimpleName())).onErrorResume(Throwable.class,e-fallback(bizType,messages,e));}privateMonoVoidfallback(StringbizType,ListPushMessagemessages,Throwablee){if(einstanceofCallNotPermittedException){// 熔断开启写入死信队列稍后重推returnMono.fromRunnable(()-deadLetterQueue.offer(bizType,messages));}// 其他异常按用户维度降级为只推在线用户ListPushMessageonlineOnlymessages.stream().filter(m-connectionManager.isOnline(m.getUserId())).toList();returnMono.fromRunnable(()-doPushBatch(onlineOnly));}}熔断配置核心参数按业务类型隔离参数默认值说明failureRateThreshold50%50% 失败率开启熔断slowCallRateThreshold80%慢调用比例阈值slowCallDurationThreshold500ms超过即视为慢调用waitDurationInOpenState20s熔断后等待半开时间permittedNumberOfCallsInHalfOpenState10半开探针数量05 上下文传播与可观测性定位线上问题不抓瞎长连接服务的问题定位非常困难一条消息可能经过 Kafka、Netty、业务 Handler 多个线程。要求每个阶段都携带TraceId并通过 Micrometer 暴露连接数、推送 QPS、 延迟、错误率等核心指标。publicclassTraceContextHandlerextendsChannelDuplexHandler{privatestaticfinalAttributeKeyStringTRACE_IDAttributeKey.valueOf(traceId);OverridepublicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){if(msginstanceofPushPacketpacket){StringtraceIdpacket.getTraceId()!null?packet.getTraceId():TraceIdGenerator.next();ctx.channel().attr(TRACE_ID).set(traceId);try(MDC.MDCCloseableignoredMDC.putCloseable(traceId,traceId)){ctx.fireChannelRead(packet);}}else{ctx.fireChannelRead(msg);}}Overridepublicvoidwrite(ChannelHandlerContextctx,Objectmsg,ChannelPromisepromise){if(msginstanceofPushPacketpacket){StringtraceIdctx.channel().attr(TRACE_ID).get();if(traceId!null)packet.setTraceId(traceId);}ctx.write(msg,promise);}}指标埋点 RED 四类类型指标名说明Ratepush_messages_total按 bizType / status 标签聚合Errorspush_errors_total区分 timeout / backpressure / circuit_openDurationpush_latency_secondsP50 / P99 / P999 直方图Saturationnetty_connectionsGauge 实时连接数与水位06 生产踩坑真金白银买来的经验坑 1Epoll 不可用却未兜底连接数上不去部分容器镜像缺少 native epoll 库Netty 会静默回退到 NIO但性能直接腰斩。修复启动时检测Epoll.isAvailable()不可用时告警同时用-Dio.netty.noUnsafefalse开启堆外内存。坑 2只读空闲不检测僵尸连接耗尽文件句柄客户端断网不会立即触发 TCP FIN导致服务端维持大量死连接。修复IdleStateHandler必须同时配置读/写空闲读空闲超 90s 强制关闭并配合应用层心跳确认。坑 3ByteBuf 引用计数泄漏凌晨 OOM自定义 Handler 中忘记release()或重复释放都会触发内存泄漏。修复启用ResourceLeakDetector.Level.PARANOID在测试环境抓泄漏生产使用SimpleChannelInboundHandler自动释放。坑 4发布时直接 kill -9消息丢失 连接雪崩滚动发布时粗暴退出未写出的消息和内存队列全部丢失。修复注册 JVM ShutdownHook先标记节点为 offline、停止接收新连接、等待 30s 让在途消息 flush再优雅关闭 EventLoop。坑 5全量广播没有做分片瞬间打满内网带宽百万用户同时推送时如果不做本地过滤所有节点会互相同步用户在线状态。修复Kafka 按 userId 取模路由到 Partition消费者只推送本节点持有的连接实现本地广播。07 总结百万长连接推送网关的核心 checklist连接治理用户-Channel 双向索引 单点登录踢人 优雅下线。背压限流全局 QPS 限流 写水位 在途消息数三重保护。熔断降级按业务类型隔离熔断失败消息入死信队列。可观测性TraceId 全链路传递 RED 指标 慢连接/死连接监控。内核调优ulimit、tcp_keepalive、epoll、零拷贝、对象池缺一不可。Netty 本身只是工具真正决定上线稳定性的是对边界条件的敬畏慢客户端、断网、发布、广播、内存泄漏每一项都可能在凌晨把你叫起来。希望这篇实战能帮你少踩几个坑。

相关新闻

C++事件驱动编程实战:eventpp库核心组件与应用架构解析

C++事件驱动编程实战:eventpp库核心组件与应用架构解析

1. 项目概述:为什么我们需要 eventpp?如果你写过C的网络服务、游戏引擎或者任何需要处理大量异步事件的程序,肯定对“事件驱动”和“回调地狱”这两个词深有体会。传统的做法,要么是手搓一堆std::function和std::bind,…

2026/7/30 9:54:56 阅读更多 →
3步快速恢复QQ空间历史数据:GetQzonehistory完整指南

3步快速恢复QQ空间历史数据:GetQzonehistory完整指南

3步快速恢复QQ空间历史数据:GetQzonehistory完整指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾经想过找回那些被时间淹没的QQ空间记忆?那些青涩的…

2026/7/30 9:54:56 阅读更多 →
NBTExplorer完整使用指南:掌握Minecraft数据编辑的终极工具

NBTExplorer完整使用指南:掌握Minecraft数据编辑的终极工具

NBTExplorer完整使用指南:掌握Minecraft数据编辑的终极工具 【免费下载链接】NBTExplorer A graphical NBT editor for all Minecraft NBT data sources 项目地址: https://gitcode.com/gh_mirrors/nb/NBTExplorer NBTExplorer是一款功能强大的图形化NBT编辑…

2026/7/30 9:54:56 阅读更多 →

最新新闻

不熬夜的毕业秘诀[特殊字符]终于不用硬撑着写论文了

不熬夜的毕业秘诀[特殊字符]终于不用硬撑着写论文了

毕业季最消耗人的,从来不是论文难度本身。 是反复被导师打回的焦虑、是格式改不完的烦躁、是文献梳理毫无头绪、是答辩临近的手足无措。 以前总觉得,别人顺利毕业都是靠硬熬,后来才发现:选对工具,真的可以少走所有弯…

2026/7/30 10:05:00 阅读更多 →
Android Bitmap内存优化全解析:从原理到实战避坑指南

Android Bitmap内存优化全解析:从原理到实战避坑指南

1. 项目概述:从“内存怪兽”到性能基石在安卓开发的世界里,Bitmap(位图)是一个让人又爱又恨的存在。爱它,是因为它是图像展示的绝对核心,从应用图标到高清大图,从滤镜效果到游戏贴图&#xff0c…

2026/7/30 10:05:00 阅读更多 →
Cocos Creator跨平台游戏开发:从核心架构到性能优化实战

Cocos Creator跨平台游戏开发:从核心架构到性能优化实战

1. 项目概述:为什么Cocos引擎值得每一位开发者关注? 如果你是一名游戏开发者,或者对游戏开发感兴趣,那么“Cocos引擎”这个名字你一定不陌生。但你可能不知道的是,它早已不是那个只做2D小游戏的“轻量级”工具了。今天…

2026/7/30 10:05:00 阅读更多 →
魔兽争霸3终极辅助:3分钟快速配置WarcraftHelper完全指南

魔兽争霸3终极辅助:3分钟快速配置WarcraftHelper完全指南

魔兽争霸3终极辅助:3分钟快速配置WarcraftHelper完全指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为《魔兽争霸3》这款经典游戏…

2026/7/30 10:05:00 阅读更多 →
国内去哪里找NAATI三级翻译?NAATI翻译件办理渠道都有哪些?

国内去哪里找NAATI三级翻译?NAATI翻译件办理渠道都有哪些?

截至2026年7月,国内办理NAATI翻译有四条路径:微信/支付宝小程序“慧办好”、国内线下翻译公司、澳洲本地翻译公司,以及NAATI官网译员目录。先纠正一个误区:“NAATI三级翻译”是旧体系中Level 3 Professional Translator的中文叫法…

2026/7/30 10:05:00 阅读更多 →
大模型实战:DeepSeek-V3.2与Qwen3.5全流程开发指南

大模型实战:DeepSeek-V3.2与Qwen3.5全流程开发指南

1. 项目概述作为一名长期从事大模型研发的算法工程师,我想分享最近在DeepSeek-V3.2和Qwen3.5两个主流大模型上的实战经验。这两个模型在中文理解和生成任务上表现出色,但在实际应用中,从训练到部署的每个环节都存在大量技术细节需要关注。本文…

2026/7/30 10:03:59 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻