Netty 基本概念以及核心组件

Netty 概述

Netty 是一个异步事件驱动的网络应用程序框架,用于快速开发高性能、高可靠的网络 IO 程序。Netty 是基于 NIO 的,它封装了 jdk 的 NIO,让我们使用起来更加方法灵活。

  1. Netty 是一个异步的、基于事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络 IO 程序。
  2. Netty 本质是一个基于 Java NIO 的框架,适用于服务器通讯相关的多种应用场景。
  3. Netty 主要针对在 TCP 协议下,面向客户端的高并发应用,或者 Peer-to-Peer 场景下的大量数据持续传输的应用。

NIO 的存在的问题(缺点)

  • Java NIO 的类库和 API 繁杂,使用麻烦,需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。
  • 需要熟悉 Java 多线程编程。这是因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网络编程非常熟悉,才能写出高质量的 NIO 程序。
  • 开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等等。
  • JDK NIOBug:臭名昭著的 epoll bug。它会导致 Selector 空轮询,最终导致 CPU 100%。直到 JDK1.7 版本依然没得到根本性的解决。

Netty 的应用场景

Netty 可构建高性能、低延时的各种 Java 中间件,例如 MQ、分布式服务框架、ESB消息总线等,Netty 主要作为基础通信框架提供高性能、低子延时的通信服务;典型的应用有:阿里分布式服务框架 DubboRPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信;还有 RocketMQ 也是使用 Netty 作为通讯的基础。

Netty 作为高性能的基础通信组件,提供了 TCP/UDPHTTP 协议栈,方便定制和开发私有协议栈,账号登录服务器。

Netty 的特点是什么?

  • 高并发:Netty 是基于 Java NIO(Nonblocking IO,非阻塞IO)开发的网络通信框架,对比于 BIO(Blocking I/O,阻塞IO),它的并发性能更高。

  • 传输快:Netty 的传输依赖于零拷贝特性,尽量减少不必要的内存拷贝,实现了更高效率的传输。

  • 方便易用:Netty 封装了 NIO 操作的很多细节,提供了易于使用调用接口。

Netty 基本概念以及核心组件_第1张图片


Netty 的模块组件

Channel

Reactor 模式和通道紧密相关,反应器(EventLoop)的查询和分发的 IO 事件都来自 Channel 组件

Channel 提供异步的网络 I/O 操作(如建立连接,读写,绑定端口),异步调用意味着任何 I/O 调用都将立即返回,并且不保证在调用结束时所请求的 I/O 操作已完成。

不同协议、不同的阻塞类型的连接都有不同的 Channel 类型与之对应。

Selector

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

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

Handler(ChannelHandler)

无论是服务端代码中自定义的 NettyServerHandler,还是客户端代码中自定义的 NettyClientHandler,都继承于 ChannelInboundHandlerAdapter,ChannelInboundHandlerAdapter 又继承于 ChannelHandlerAdapter,ChannelHandlerAdapter 又实现了 ChannelHandler 接口。

ChannelHandler 是一个接口,处理 I/O 事件或拦截 I/O 操作,并将其转发到其 ChannelPipeline 中的下一个 ChannelHandler。因此多个 ChannelHandler 形成一个责任链,责任链位于 ChannelPipeline 中。

  • ChannelInboundHandlerAdapter 用于处理入站 IO 事件
  • ChannelOutboundHandlerAdapter 用于处理出站 IO 事件

Pipeline(ChannelPipeline)

ChannelPipeline 是一个 Handler 的集合,它负责处理和拦截 Channel 的入站事件和出站操作,相当于一个贯穿 Netty 的链。ChannelPipeline 实现了一种高级形式的拦截过滤器模式,使用户可以完全控制事件的处理方式,以及 Channel 中各个的 ChannelHandler 如何相互交互。

Netty 中每个 Channel 都有且仅有一个 ChannelPipeline 与之对应,它们的组成关系如下:

Netty 基本概念以及核心组件_第2张图片

一个 Channel 包含了一个 ChannelPipeline,而 ChannelPipeline 中又维护了一个由 ChannelHandlerContext 组成的双向链表,并且每个 ChannelHandlerContext 中又关联着一个 ChannelHandler。入站事件和出站事件在一个双向链表中,入站事件会从链表 head 往后传递到最后一个入站的 handler,出站事件会从链表 tail 往前传递到最前一个出站的 handler,两种类型的 handler 互不干扰。

NioEventLoop 内部采用串行化设计,从消息的 读取->解码->处理->编码->发送,始终由 IO 线程 NioEventLoop 负责。

EventLoop

在 Netty 中,一个 EventLoop 相当于一个子反应器(SubReactor),一个 NioEventLoop 子反应器拥有一个事件轮询线程

每一个 NioEventLoop 拥有一个 Java NIO 选择器以及一个 taskQueue ,Selector 用于实现 I/O 多路复用,taskQueue 的目的是在任务提交的速度大于线程的处理速度的时候起到缓冲作用,或者用于异步处理 Selector 监听到的 IO 事件。如果 Handler 有一些长时间的业务处理,可以交给 taskQueue 异步处理

同时 Selector 以及 taskQueue 共用一个线程,用单线程的方式串行执行队列中的 task。

EventLoopGroup(NioEventLoopGroup)

多个 EventLoop 线程放在一起,可以组成一个 EventLoopGroup。EventLoopGroup 提供 next 接口,可以从组里面按照一定规则(如轮询)获取其中一个 EventLoop 来处理任务。

为了及时接收到新连接,在服务器端,一般有两个独立的反应器,一个负责新连接的监听和接收,另一个负责 IO 事件轮询和分发。对应到 Netty 的服务器程序中,则需要设置两个 EventLoopGroup 线程组,一个 EventLoopGroup 负责新连接的监听和接收——Boss 线程组;另一个负责 IO 事件轮询和分发,并执行 Handler 处理器中的业务处理——Worker 线程组

Netty 基本概念以及核心组件_第3张图片

你可能感兴趣的:(Netty,java,网络,netty)