前言
Netty 入门与实战:仿写微信 IM 即时通讯系统阅读总结
编程模型
1.传统IO编程
每个连接创建成功之后都需要一个线程来维护,每个线程包含一个 while 死循环,那么 1w 个连接对应 1w 个线程,继而 1w 个 while 死循环
1 | * 线程资源受限:线程是操作系统中非常宝贵的资源,同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费,操作系统耗不起 |
2.NIO编程模型
NIO 编程模型中,新来一个连接不再创建一个新的线程,而是可以把这条连接直接绑定到某个固定的线程,然后这条连接所有的读写都由这个线程来负责
1 | * NIO 模型中通常会有两个线程,每个线程绑定一个轮询器 selector ,serverSelector负责轮询是否有新的连接,clientSelector负责轮询连接是否有数据可读 |
Netty编程
1.服务端启动流程
1 | * 创建一个引导类,然后给他指定线程模型,IO模型,连接读写处理逻辑,绑定端口之后,服务端就启动起来了 |
2.客户端启动流程
1 | * 与服务端启动类似。调用 connect 方法进行连接,返回Future,异步监听是否连接成功。可以增加 |
3.客户端与服务端双向通信
1 | * initChannel() 方法添加逻辑处理器 |
4.ByteBuf
1 | * 基于读写指针和容量、最大可扩容容量,衍生出一系列的读写方法 |
5.客户端与服务端通信协议编解码。扩展阅读RPC 消息协议
1 | 自定义通信协议 |
6.实现客户端与服务端收发消息
1 | * channel 的 attr() 绑定属性来设置某些状态,获取某些状态,不需要额外的 map 来维持。 |
7.pipeline 与 channelHandler
1 | * ChannelPipeline 是一个双向链表结构,他和 Channel 之间是一对一的关系。 |
8.构建客户端与服务端 pipeline
1 | * 基于 SimpleChannelInboundHandler,不再需要强转,不再有冗长乏味的 if else 逻辑,不需要手动传递对象。(对比ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter理解) |
9.拆包粘包理论与解决方案
1 | * 1. 固定长度的拆包器 FixedLengthFrameDecoder |
10.channelHandler 的生命周期
1 | * ChannelHandler 启动时回调方法的执行顺序为:handlerAdded() -> channelRegistered() -> channelActive() -> channelRead() -> channelReadComplete() |
11.使用 channelHandler 的热插拔实现客户端身份校验
1 | * 如果有很多业务逻辑的 handler 都要进行某些相同的操作,我们完全可以抽取出一个 handler 来单独处理 |
12.客户端互聊原理与实现
1 | * channel.attr(Attributes.SESSION).set(session) 绑定session |
13.群聊的发起与通知
1 | * ChannelGroup channelGroup = new DefaultChannelGroup(ctx.executor()); |
性能优化篇
1.Netty性能优化
1 | * 共享 handler |
2.心跳与空闲检测
1 | * 空闲检测 IdleStateHandler ,连接假死之后会回调 channelIdle() 方法 |