分布式学习笔记---分布式架构网络通信-Netty

分布式学习笔记—分布式架构网络通信-Netty

1.Netty简介

  1. Netty 是由 JBOSS 提供一个异步的、 基于事件驱动的网络编程框架。
  2. Netty 可以帮助你快速、 简单的开发出一 个网络应用, 相当于简化和流程化了 NIO 的开发过程。
  3. 作为当前最流行的 NIO 框架, Netty 在互联网领域、 大数据分布式计算领域、 游戏行业、 通信行业等获得了广泛的应用, 知名的 Elasticsearch 、 Dubbo 框架内部都采用了 Netty。
  4. 从图中就能看出 Netty 的强大之处:零拷贝、可拓展事件模型;支持 TCP、UDP、HTTP、WebSocket 等协议;提供安全传输、压缩、大文件传输、编解码支持等等。
  5. 具备以下优点:
    1. 设计优雅,提供阻塞和非阻塞的 Socket;提供灵活可拓展的事件模型;提供高度可定制的线程模型。
    2. 具备更高的性能和更大的吞吐量,使用零拷贝技术最小化不必要的内存复制,减少资源的消耗。
    3. 提供安全传输特性。
    4. 支持多种主流协议;预置多种编解码功能,支持用户开发私有协议。
      分布式学习笔记---分布式架构网络通信-Netty_第1张图片

2. 为什么使用Netty

2-1.NIO缺点:

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

2-2.Netty优点:

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

3. 线程模型

  1. 单线程模型
    分布式学习笔记---分布式架构网络通信-Netty_第2张图片
  2. 线程池模型
    1. 左边会单独起一个线程,查看有没有用户进行连接
    2. 在右边会维护一个线程池,线程池里面会创建多个线程,有读写操作的时候会在线程池里进行操作
    3. 如果此时用户特别多,但是只有一个单线程,此时处理能力就变得比较低下
      分布式学习笔记---分布式架构网络通信-Netty_第3张图片
  3. Netty模型
    分布式学习笔记---分布式架构网络通信-Netty_第4张图片
    1. Netty 抽象出两组线程池, BossGroup 专门负责接收客 户端连接, WorkerGroup 专门负责网络读写操作。
    2. NioEventLoop 表示一个不断循环执行处理 任务的线程, 每个 NioEventLoop 都有一个 selector, 用于监听绑定在其上的 socket 网络通道。
    3. NioEventLoop 内部采用串行化设计, 从消息的读取->解码->处理->编码->发送, 始终由 IO 线 程 NioEventLoop 负责。

4. Netty的核心组件

4-1:ChannelHandler及其实现类 ,ChannelHandler本身是个接口

  1. ChannelHandler 接口定义了许多事件处理的方法, 我们可以通过重写这些方法去实现具 体的业务逻辑
  2. 我们经常需要自定义一个 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)
    

4-2:ChannelPipeline

  1. ChannelPipeline 是一个 Handler 的集合, 它负责处理和拦截 inbound 或者 outbound 的事 件和操作, 相当于一个贯穿 Netty 的链。
    //把一个业务处理类(handler) 添加到链中的第一 个位置
    ChannelPipeline addFirst(ChannelHandler... handlers)
    // 把一个业务处理类(handler) 添加到链中的最后 一个位置
    ChannelPipeline addLast(ChannelHandler... handlers)
    

分布式学习笔记---分布式架构网络通信-Netty_第5张图片

4-3:ChannelHandlerContext

  1. 这 是 事 件 处 理 器 上 下 文 对 象 , Pipeline 链 中 的 实 际 处 理 节 点 。
  2. 每 个 处 理 节 点ChannelHandlerContext 中 包 含 一 个 具 体 的 事 件 处 理 器 ChannelHandler ,
  3. 同 时ChannelHandlerContext 中也绑定了对应的 pipeline 和 Channel 的信息,方便对 ChannelHandler 进行调用。
  4. 常用方法如下所示:
    1. ChannelFuture close(), 关闭通道
    2. ChannelOutboundInvoker flush(), 刷新
    3. ChannelFuture writeAndFlush(Object msg) , 将 数 据 写 到 ChannelPipeline 中
    4. ChannelHandler 的下一个 ChannelHandler 开始处理(出站)

4-4:ChannelFuture

  1. 表示 Channel 中异步 I/O 操作的结果, 在 Netty 中所有的 I/O 操作都是异步的, I/O 的调 用会直接返回, 调用者并不能立刻获得结果, 但是可以通过 ChannelFuture 来获取 I/O 操作 的处理状态。
  2. 常用方法如下所示:
    Channel channel(), 返回当前正在进行 IO 操作的通道 
    ChannelFuture sync(), 等待异步操作执行完毕
    

4-5:EventLoopGroup 和其实现类 NioEventLoopGroup

  1. EventLoopGroup 是一组 EventLoop(可以理解为是一个线程)的抽象, Netty 为了更好的利用多核 CPU 资源, 一般会有多个 EventLoop同时工作, 每个 EventLoop 维护着一个 Selector 实例。
  2. EventLoopGroup 提供 next 接口, 可以从组里面按照一定规则获取其中一个 EventLoop 来处理任务。
  3. 在 Netty 服务器端编程中, 我们一般都需要提供两个EventLoopGroup, 例如: BossEventLoopGroup 和WorkerEventLoopGroup
    - public NioEventLoopGroup(), 构造方法
    - public Future<?> shutdownGracefully(), 断开连接, 关闭线程
    

4-6:ServerBootstrap 和 Bootstrap

  1. ServerBootstrap 是 Netty 中的服务器端启动助手,通过它可以完成服务器端的各种配置; Bootstrap 是 Netty 中的客户端启动助手, 通过它可以完成客户端的各种配置。 常用方法如下所示:
    	//该方法用于 服务器端, 用来设置两个 EventLoop 
    	public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup)
    	//该方法用于客户端, 用来设置一个 EventLoop
    	public B group(EventLoopGroup group) 
    	//该方法用来设置一个服务器端的通道实现
    	public B channel(Class<? extends C> channelClass) 
    	//用来给 ServerChannel 添加配置
    	public <T> B option(ChannelOption<T> option, T value)
    	//用来给接收到的 通道添加配置
    	public <T> ServerBootstrap childOption(ChannelOption<T> childOption, T value)
    	//该方法用来设置业务处理类(自定 义的 handler)
    	public ServerBootstrap childHandler(ChannelHandler childHandler)
    	//该方法用于服务器端, 用来设置占用的端口号
    	public ChannelFuture bind(int inetPort)
    	//该方法用于客户端, 用来连接服务器端
    	public ChannelFuture connect(String inetHost, int inetPort)
    

5.基于Netty自定义RPC

RPC又称远程过程调用,我们所知的远程调用分为两种,现在在服务间通信的方式也基本以这两种为主
  1. 是基于HTTP的restful形式的广义远程调用,以spring could的feign和restTemplate为代表,采用的协议是HTTP的7层调用协议,并且协议的参数和响应序列化基本以JSON格式和XML格式为主。
  2. 是基于TCP的狭义的RPC远程调用,以阿里的Dubbo为代表,主要通过netty来实现4层网络协议,NIO来异步传输,序列化也可以是JSON或者hessian2以及java自带的序列化等,可以配置。
  3. 服务端与客户端之间的关系梳理
    分布式学习笔记---分布式架构网络通信-Netty_第6张图片

你可能感兴趣的:(分布式)