文章目录

  • Netty简介
  • Netty结构
  • Netty线程模型
  • 服务端线程模型
  • 客户端线程模型
  • NioEventLoop
  • Task
  • Netty中的Channel
  • 工作原理
  • 线程
  • ChannelPipeline和ChannelHandler
  • ChannelHandlerContext
  • ChannelHandler


Netty简介

Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。

Netty结构

netty 架构图解析 netty 结构_netty


NioEventLoop采用串行化设计理念:

NioEventLoop线程池中有若干个NioEventLoop线程,每一个NioEventLoop线程串行执行Handler链;每当有一个客户端接入,从线程池中获取一个可用的NioEventLoop线程,当数组到达上限之后,从0开始(负载均衡);每个客户端连接一个线程,这样保证了数据的安全性(避免多个线程同时访问)

Netty线程模型

netty 架构图解析 netty 结构_客户端_02

  • Acceptor中的NioEventLoop用于接收TCP连接,初始化参数
  • I/O线程池中的NioEventLoop异步读取通信对端的数据报,发送读事件到channel
  • 异步发送消息到对端,调用channel的消息发送接口
  • 执行系统调用Task
  • 执行定时Task

服务端线程模型

一种比较流行的做法是服务端监听线程和IO线程分离,类似于Reactor的多线程模型,它的工作原理图如下:

netty 架构图解析 netty 结构_客户端_03

客户端线程模型

netty 架构图解析 netty 结构_netty 架构图解析_04

NioEventLoop

NioEventLoop是Netty的Reactor线程,它在Netty Reactor线程模型中的职责如下:

  1. 作为服务端Acceptor线程,负责处理客户端的请求接入
  2. 作为客户端Connecor线程,负责注册监听连接操作位,用于判断异步连接结果
  3. 作为IO线程,监听网络读操作位,负责从SocketChannel中读取报文
  4. 作为IO线程,负责向SocketChannel写入报文发送给对方,如果发生写半包,会自动注册监听写事件,用于后续继续发送半包数据,直到数据全部发送完成

如下图,是一个NioEventLoop的处理链:

netty 架构图解析 netty 结构_服务端_05

  • 处理链中的处理方法是串行化执行的
  • 一个客户端连接只注册到一个NioEventLoop上,避免了多个IO线程并发操作

Task

Netty Reactor线程模型中有两种Task:系统Task和定时Task

  • 系统Task:创建它们的主要原因是,当IO线程和用户线程都在操作同一个资源时,为了防止并发操作时锁的竞争问题,将用户线程封装为一个Task,在IO线程负责执行,实现局部无锁化
  • 定时Task:主要用于监控和检查等定时动作

基于以上原因,NioEventLoop不是一个纯粹的IO线程,它还会负责用户线程的调度

参考:
IO多路复用之select、poll、epoll详解:

Netty中的Channel

Channel是Netty的核心概念之一,它是Netty网络通信的主体,由它负责同对端进行网络通信、注册和数据操作等功能。

工作原理

netty 架构图解析 netty 结构_netty_06


如上图所示:

1.一旦用户端连接成功,将新建一个channel同该用户端进行绑定
2.channel从EventLoopGroup获得一个EventLoop,并注册到该EventLoop,channel生命周期内都和该EventLoop在一起(注册时获得selectionKey)
3.channel同用户端进行网络连接、关闭和读写,生成相对应的event(改变selectinKey信息),触发eventloop调度线程进行执行
4.如果是读事件,执行线程调度pipeline来处理用户业务逻辑

线程

多个channel可以注册到一个eventloop上,所有的操作都是顺序执行的,eventloop会依据channel的事件调用channel的方法进行相关操作,每个channel的操作和处理在eventloop中都是顺序的,如下图:

netty 架构图解析 netty 结构_服务端_07

ChannelPipeline和ChannelHandler

ChannelPipeline和ChannelHandler用于channel事件的拦截和处理,Netty使用类似责任链的模式来设计ChannelPipeline和ChannelHandler

ChannelPipeline相当于ChannelHandler的容器,channel事件消息在ChannelPipeline中流动和传播,相应的事件能够被ChannelHandler拦截处理、传递、忽略或者终止,如下图所示:

netty 架构图解析 netty 结构_线程模型_08

ChannelHandlerContext

每个ChannelHandler 被添加到ChannelPipeline 后,都会创建一个ChannelHandlerContext 并与之创建的ChannelHandler 关联绑定。如下图:

netty 架构图解析 netty 结构_服务端_09


ChannelHandler通过ChannelHandlerContext来操作channel和channelpipeline

ChannelHandler

ChannelHandler负责I/O事件或者I/O操作进行拦截和处理,用户可以通过ChannelHandlerAdapter来选择性的实现自己感兴趣的事件拦截和处理。
由于Channel只负责实际的I/O操作,因此数据的编解码和实际处理都需要通过ChannelHandler进行处理。

注:
ChannelPipeline是线程安全的,多个业务线程可以并发的操作ChannelPipeline;ChannelHandler不是线程安全的,用户需要自己保重ChannelHandler的线程安全