netty

网络编程框架:网络通讯用的,要先看udp,tcp,最主要是看socket网络编程。


为什么会造成粘包和拆包?TCP建立的是长连接,和缓冲区造成

Tcp协议为了能够高性能传输,发送和接受采用缓存区

1. 当我们客户端发送的数据消息<我们服务器读取的缓冲区的大小  会发生粘包

2. 当我们客户端发送的数据消息>我们服务器读取的缓冲区的大小  会发生拆包

3. 接收端不够及时的获取缓冲区的数据,也会产生粘包的问题

4. 进行mss(最大报文长度)大小的TCP分段,当tcp报文长度-tcp头部长度>mss的时候会发生拆包

什么是Netty?

Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。
Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke's Choice Award,见https://www.java.net/dukeschoice/2011)。它活跃和成长于用户社区,像大型公司 Facebook 和 Instagram 以及流行 开源项目如 Infinispan, HornetQ, Vert.x, Apache Cassandra 和 Elasticsearch 等,都利用其强大的对于网络抽象的核心代码。

为什么Netty受欢迎?

如第一部分所述,netty是一款收到大公司青睐的框架,在我看来,netty能够受到青睐的原因有三:

  1. 并发高
  2. 传输快
  3. 封装好

Netty为什么并发高

Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高,两张图让你了解BIO和NIO的区别:

Channel

数据传输流,与channel相关的概念有以下四个,上一张图让你了解netty里面的Channel。  


  • Channel,表示一个连接,可以理解为每一个请求,就是一个Channel。
  • ChannelHandler,核心处理业务就在这里,用于处理业务请求。
  • ChannelHandlerContext,用于传输业务数据。
  • ChannelPipeline,用于保存处理过程需要用到的ChannelHandler和ChannelHandlerContext。
  • ByteBuf是一个存储字节的容器,最大特点就是使用方便,它既有自己的读索引和写索引,方便你对整段字节缓存进行读写,也支持get/set,方便你对其中每一个字节进行读写,他的数据结构如下图所示:
  • Codec
    Netty中的编码/解码器,通过他你能完成字节与pojo、pojo与pojo的相互转换,从而达到自定义协议的目的。
    在Netty里面最有名的就是HttpRequestDecoder和HttpResponseEncoder了。

    Netty 的特点

    Netty 对 JDK 自带的 NIO 的 API 进行了封装,解决了上述问题。

    Netty的主要特点有:

    1)设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池;真正的无连接数据报套接字支持(自 3.1 起)。

    2)使用方便:详细记录的 Javadoc,用户指南和示例;没有其他依赖项,JDK 5(Netty 3.x)或 6(Netty 4.x)就足够了。

    3)高性能、吞吐量更高:延迟更低;减少资源消耗;最小化不必要的内存复制。

    4)安全:完整的 SSL/TLS 和 StartTLS 支持。

    5)社区活跃、不断更新:社区活跃,版本迭代周期短,发现的 Bug 可以被及时修复,同时,更多的新功能会被加入。NioSocketChannel,异步的客户端 TCP Socket 连接。

    NioServerSocketChannel,异步的服务器端 TCP Socket 连接。

    NioDatagramChannel,异步的 UDP 连接。

    NioSctpChannel,异步的客户端 Sctp 连接。

    NioSctpServerChannel,异步的 Sctp 服务器端连接,这些通道涵盖了 UDP 和 TCP 网络 IO 以及文件 IO。

    【Selector】:

    Netty 基于 Selector 对象实现 I/O 多路复用,通过 Selector 一个线程可以监听多个连接的 Channel 事件。

    当向一个 Selector 中注册 Channel 后,Selector 内部的机制就可以自动不断地查询(Select) 这些注册的 Channel 是否有已就绪的 I/O 事件(例如可读,可写,网络连接完成等),这样程序就可以很简单地使用一个线程高效地管理多个 Channel 。

    【NioEventLoop】:

    NioEventLoop 中维护了一个线程和任务队列,支持异步提交执行任务,线程启动时会调用 NioEventLoop 的 run 方法,执行 I/O 任务和非 I/O 任务:

    I/O 任务,即 selectionKey 中 ready 的事件,如 accept、connect、read、write 等,由 processSelectedKeys 方法触发。

    非 IO 任务,添加到 taskQueue 中的任务,如 register0、bind0 等任务,由 runAllTasks 方法触发。

    两种任务的执行时间比由变量 ioRatio 控制,默认为 50,则表示允许非 IO 任务执行的时间与 IO 任务的执行时间相等。

    【NioEventLoopGroup】:

    NioEventLoopGroup,主要管理 eventLoop 的生命周期,可以理解为一个线程池,内部维护了一组线程,每个线程(NioEventLoop)负责处理多个 Channel 上的事件,而一个 Channel 只对应于一个线程。

    【ChannelHandler】:

    ChannelHandler 是一个接口,处理 I/O 事件或拦截 I/O 操作,并将其转发到其 ChannelPipeline(业务处理链)中的下一个处理程序。

    1. ChannelHandler 本身并没有提供很多方法,因为这个接口有许多的方法需要实现,方便使用期间,可以继承它的子类:  

     服务端 Netty 的工作架构图: