Netty学习笔记

资料参考来源拉钩Java高薪训练营

文章目录


一、Netty简介

Netty 是由 JBOSS 提供一个异步的、 基于事件驱动的网络编程框架。

Netty 可以帮助你快速、简单的开发出一个网络应用,相当于简化和流程化了 NIO 的开发过程。作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,知名的Elasticsearch 、Dubbo 框架内部都采用了Netty。

NIO缺点

  • NIO 的类库和 API 繁杂,使用麻烦。你需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等.
  • 可靠性不强,开发工作量和难度都非常大.
  • NIO 的 Bug,例如 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%.

Netty优点

  • 对各种传输协议提供统一的 API
  • 高度可定制的线程模型——单线程、一个或多个线程池
  • 更好的吞吐量,更低的等待延迟
  • 更少的资源消耗
  • 最小化不必要的内存拷贝

netty模型:
Netty学习笔记
Netty 抽象出两组线程池, BossGroup 专门负责接收客户端连WorkerGroup 专门负责网络读写操作。

NioEventLoop表示一个不断循环执行处理 任务的线程,每个NioEventLoop 都有一个 selector, 用于监听绑定在其上的 socket 网络通道。

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

二、Netty核心组件

1.ChannelHandler

ChannelHandler 接口定义了许多事件处理的方法, 我们可以通过重写这些方法去实现具体的业务逻辑。
我们经常需要自定义一个 Handler 类去继ChannelInboundHandlerAdapter,可以重写一下方法:

public void channelActive(ChannelHandlerContext ctx), 通道就绪事件
public void channelRead(ChannelHandlerContext ctx, Object msg), 通道读取数据事件
public void channelReadComplete(ChannelHandlerContext ctx) , 数据读取完毕事件
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause), 通道发生异常事件

2.ChannelPipeline

ChannelPipeline 是一个 Handler 的集合,它负责处理和拦截 inbound 或者 outbound 的事 件和操作,相当于一个贯穿 Netty 的链。

ChannelPipeline addFirst(ChannelHandler... handlers),把一个业务处理类(handler)添加到链中的第一个位置
ChannelPipeline addLast(ChannelHandler... handlers),把一个业务处理类(handler)添加到链中的最后一个位置

Netty学习笔记

3.ChannelHandlerContext

事件处理器上下文对象,Pipeline链中的实际处理节点。每个处理节点ChannelHandlerContext中包含一个具体的事件处理器ChannelHandler,同 时ChannelHandlerContext中也绑定了对应的pipeline和Channel的信息,方便对ChannelHandler进行调用。

ChannelFuture close(),关闭通道
ChannelOutboundInvoker flush(),刷新
ChannelFuture writeAndFlush(Object msg),将数据写到ChannelPipeline中当前ChannelHandler,并且下一个ChannelHandler开始处理

4.ChannelFuture

表示Channel 中异步I/O操作的结果,在Netty中所有的I/O操作都是异步的,I/O的调用会直接返回,调用者并不能立刻获得结果,但是可以通过ChannelFuture来获取I/O操作的处理状态。

Channel channel(),返回当前正在进行IO操作的通道
ChannelFuture sync(),等待异步操作执行完毕

5.EventLoopGroup和实现类NioEventLoopGroup

EventLoopGroup是一组EventLoop的抽象,Netty为了更好的利用多核 CPU 资源,一般会有多个EventLoop同时工作,每个EventLoop维护着一个Selector实例。EventLoopGroup提供next接口,可以从组里面按照一定规则获取其中一个 EventLoop 来处理任务。在Netty服务器端编程中,我们一般都需要提供两个EventLoopGroup,例如:BossEventLoopGroup和WorkerEventLoopGroup。

public NioEventLoopGroup(),构造方法
public Future<?> shutdownGracefully(),断开连接,关闭线程

6.ServerBootstrap和Bootstrap

ServerBootstrap是Netty中的服务器端启动助手,通过它可以完成服务器端的各种配置。
Bootstrap是Netty中的客户端启动助手,通过它可以完成客户端的各种配。

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup),该方法用于服务器端,用来设置两个EventLoop
public B group(EventLoopGroup group),该方法用于客户端,用来设置一个 EventLoop
public B channel(Class<? extends C> channelClass),该方法用来设置一个服务器端的通道实现
public <T> B option(ChannelOption<T> option, T value),用来给ServerChannel 添加配置
public <T> ServerBootstrap childOption(ChannelOption<T> childOption, T value),用来给接收到的 通道添加配置
public ServerBootstrap childHandler(ChannelHandler childHandler), 该方法用来设置业务处理类(自定义的 handler)
public ChannelFuture bind(int inetPort),该方法用于服务器端,用来设置占用的端口号
public ChannelFuture connect(String inetHost, int inetPort),该方法用于客户端,用来连接服务器端

三、使用Netty开发一个简易的RPC框架

RPC全称为remote procedure call,即远程过程调用。

借助RPC可以做到像本地调用方法一样调用远程服务,是一种进程间的通信方式。在java中RPC框架比较多,常见的有Hessian、gRPC、Thrift、HSF (High Speed Service Framework)、Dubbo 等,其实对于RPC框架而言,核心模块就是通讯和序列化

这里我们使用netty来实现一个简易的RPC框架。也可以使用RMI,RMI依赖于java虚拟机,所以只支持两个JVM之间的调用。

Netty学习笔记

  • rpc-common 公用接口api
  • rpc-frame 自定义rpc框架代码
  • rcp-server 服务端
  • rcp-consumer 客户端

源码地址: https://github.com/pengtw/rpc-custom

上一篇:Netty实战三之Netty的组件和设计


下一篇:Netty实战四之传输