Netty学习记录-入门篇( 五 )


- public NioEventLoopGroup(): 构造方法- public Future<?> shutdownGracefully(): 断开连接,关闭线程Unpooled类Netty提供一个专门用来操作缓冲区(即Netty的数据容器)的工具类
常用方法如下:
public static ByteBuf copiedBuffer(CharSequence String, Charset charset):通过给定的数据和字符编码返回一个ByteBuf对象(类似于NIO中的ByteBuffer)Google Protobuf

Netty学习记录-入门篇

文章插图
Netty本身自带的 ObjectDecoderObjectEncoder可以用来实现POJO对象或各种业务对象的编码和解码,底层使用的仍然是Java序列化技术,而Java序列化技术本身效率就不高,存在如下问题:
  • 无法跨语言
  • 序列化后的体积太大,是二进制的5倍多
  • 序列化性能太低 引出新的解决方案:Google的Protobuf

Netty学习记录-入门篇

文章插图
Netty编解码器和handler的调用机制代码示例:netty-decoder模块
使用自定义的编码器和解码器来说明Netty的handler调用机制
  • 客户端发送long -> 服务器
  • 服务器发送long -> 客户端
结论:
  • 不论解码器handler还是编码器handler接收的消息类型必须与待处理的消息类型一致,否则该handler不会被执行
  • 在解码器进行数据解码时,需要判断缓存区(ByteBuf)的数据是否足够,否则接收到的结果会与期望的结果可能不一致 。
    • ReplayingDecoder扩展了ByteToMessageDecoder类,使用这个类,我们不必调用readableBytes()方法 。参数S指定了用户状态管理的类型,其中Void代表不需要状态管理 。
    • ReplayingDecoder使用方便,但它也有一些局限性:
    • 并不是所有的 ByteBuf操作都被支持,如果调用了一个不被支持的方法,将会抛出一个 UnsupportedOperationException
    • ReplayingDecoder 在某些情况下可能稍慢于 ByteToMessageDecoder,例如网络缓慢并且消息格式复杂时 , 消息会被拆成了多个碎片 , 速度变慢 。

Netty学习记录-入门篇

文章插图
TCP粘包与拆包及解决方案
  • TCP是面向连接的 , 面向流的 , 提供高可靠性服务 。收发两端(客户端和服务器端)都要有——成对的socket,因此,发送端为了将多个发送给接收端的包,更有效的发送给对方, 使用了优化算法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包 。这样做虽然提高了效率,但是接收端就难于分辨出完整的数据包了 ,  因为面向流的通信是无消息保护边界的 。

Netty学习记录-入门篇

文章插图
TCP粘包与拆包解决方案
  • 使用 自定义协议 + 编解码器 来解决
  • 关键就是要解决 服务器端每次读取数据长度的问题 , 这个问题解决 , 就不会出现服务器多读或少读数据的问题,从而避免TCP粘包、拆包 。
代码示例:
  • 要求客户端发送5个Message对象,客户端每次发送一个Message对象
  • 服务器端每次接收一个Message,分5次进行解码 , 每读取到一个Message , 会回复一个Message对象给客户端
Netty 核心源码剖析只有看过Netty源码,才能说是真的掌握了Netty框架 。
判断是否为 2 的 n 次方
private static boolean isPowerOfTwo(int val) {return (val & -val) == val;}源码解析:
  • Netty启动过程源码剖析
  • Netty接受请求过程源码剖析
  • Pipeline Handler HandlerContext创建源码剖析
  • ChannelPipeline是如何调度handler的
  • Netty心跳(heartbeat)服务源码剖析
  • Netty核心组件EventLoop源码剖析
  • handler中加入线程池和Context中添加线程池的源码剖析
用Netty 自己 实现 dubbo RPC