Netty 采用了哪些设计模式?
- 标签:Netty、后端
🏛 业务架构师
Netty 里模式密度很高,我按它支撑了什么扩展能力讲(这比背模式名有价值):
- Reactor 模式(主线):事件驱动 + 多路复用——boss/worker 主从模型是"少量线程管海量连接"的架构基石;
- 责任链(Pipeline):ChannelPipeline 里一串 ChannelHandler,编解码、业务处理逐级流转——业务可插拔自己的 handler,网关、协议栈的可扩展性全靠它。这也是我借鉴到业务侧最多的结构:风控链、审批链同构;
- 建造者模式:ServerBootstrap 链式配置——复杂配置的组装体验;
- 工厂方法:ChannelFactory、ReflectiveChannelFactory 按需创建 NioSocketChannel 等;
- 单例/静态工具:Unpooled、默认分配器;
- 观察者/回调(Future/Promise):异步结果通知——Netty 的 Future 扩展了 JDK 版,支持监听器链;
- 适配器:ChannelInboundHandlerAdapter 空实现骨架,业务只覆写关心的方法(模板方法的变体思想);
- 装饰器思想:WrappedByteBuf 增强缓冲行为。
架构视角的两个观察:
- 模式在框架里的角色是"扩展点协议":Pipeline+责任链定义了"往哪插"、Builder 定义了"怎么配"、Adapter 定义了"怎么省事地实现"——框架 = 模式组合出的扩展契约。业务方学 Netty 最该学的是它如何把"变化"安排在固定的位置;
- 模式不是装饰而是约束:handler 无状态/可共享(@Sharable)的规约、事件传播的顺序性——模式背后的纪律才是它可用的原因。
一句话:Netty 是"模式驱动的网络框架"教科书——看懂每个模式对应的扩展点,你就知道往哪里放业务逻辑。
🏗 系统架构师
Netty 的设计模式不是点缀,是骨架级使用,我按组件对应讲:
- Reactor 模式(核心架构):Boss/Worker EventLoopGroup 的主从 Reactor,事件驱动解耦并发模型;
- 责任链:ChannelPipeline + ChannelHandler——入站/出站事件沿 handler 链流动(编解码 → 业务 → 异常),动态增删、复用与业务解耦,是 Netty 扩展性的根基;也是 Web Filter/Interceptor 链的同源设计;
- 建造者模式:ServerBootstrap 链式配置(group/option/handler/childHandler);
- 工厂模式:ChannelFactory、ByteBuf 分配器(PooledByteBufAllocator/Unpooled);
- 单例:Unpooled、默认分配器等共享实例;
- 观察者/监听器:Future/GenericFutureListener——异步结果回调通知;
- 适配器:ChannelInboundHandlerAdapter 等空实现基类,按需覆盖关心的事件(模板方法的变体);
- 装饰器:WrappedByteBuf 对 ByteBuf 功能增强;
- 策略:EventLoop 选择器(RoundRobin)、多种 ByteBuf 分配策略;
- 外观:Bootstrap 统一封装复杂的启动细节。
我的解读角度:Netty 把"变化点封装成可插拔组件"做到了极致——线程模型、编解码、内存分配、传输(NIO/Epoll/Local)每个轴都可替换。这也是评估一个框架设计水准的方法论:看它预留了哪些正交的扩展轴,以及扩展时是否不需要动框架源码(开闭原则的工程兑现)。
💻 全栈开发专家
我从源码里能对上号的说:
1. Reactor 模式:NioEventLoopGroup(boss/worker)+ Selector 事件分发——主从 Reactor 的教科书实现。
2. 责任链:ChannelPipeline 里的 handler 链,ChannelHandlerContext.fireChannelRead() 逐个传递,编解码/业务/异常处理分层组织——Netty 最核心的模式。
3. 工厂方法:ReflectiveChannelFactory(channel(NioServerSocketChannel.class) 传 class 反射创建);EventExecutor 的创建也走工厂。
4. 建造者模式:ServerBootstrap/Bootstrap 链式配置(group/channel/option/childHandler),把复杂配置过程流式化。
5. 观察者/监听器:Future.addListener()——异步操作完成时回调通知,而不是阻塞 get。
6. 适配器:ChannelInboundHandlerAdapter 等一整套空实现基类,我只需要覆写关心的回调(channelRead/exceptionCaught),其余透传——模板方法的变体也在这层(生命周期骨架固定)。
7. 单例:Unpooled 的共享 buffer 实例(EMPTY_BUFFER)、各类全局 allocator。
8. 策略:EventLoopChooser(轮询/随机选择策略)、Recycler 的对象回收策略。
面试组织技巧:挑 pipeline(责任链)+ EventLoop(Reactor)+ Adapter(适配器/模板)三个展开,每个带上"源码类名 + 它解决了什么工程问题",比报菜名式罗列有说服力——比如"责任链让编解码器可插拔、异常统一兜底在 pipeline 尾部的 handler"。