Netty 框架学习 —— Netty 组件与设计
Channel、EventLoop 和 ChannelFuture
这一节将对 Channel、EventLoop 和 ChannelFuture 类进行讨论,它们组合在一起,可以被认为是 Netty 网络抽象的代表:
- Channel —— Socket
- EventLoop —— 控制流、多线程处理、并发
- CHannelFuture —— 异步通知
1. Channel 接口
Netty 的 Channel 接口对应 Java 网络编程的 Socket,大大降低了直接使用 Socket 类的复杂性。此外,Channel 也拥有其他预定义的实现类:
- EmbeddedChannel:测试 ChannelHandler
- LocalServerChannel:用于同一个 JVM 内部实现 client 和 server 之间的通信
- NioSocketChannel:异步的客户端 TCP Socket 连接
- NioServerSocketChannel:异步的服务器端 TCP Socket 连接
- NioDatagramChannel:异步的 UDP 连接
- NioSctpChannel:异步的客户端 Sctp 连接
- NioSctpServerChannel:异步的 Sctp 服务器端连接
- OioSocketChannel:同步的客户端 TCP Socket 连接
- OioServerSocketChannel:同步的服务器端 TCP Socket 连接
- OioDatagramChannel:同步的 UDP 连接
- OioSctpChannel:同步的 Sctp 服务器端连接
- OioSctpServerChannel:同步的客户端 TCP Socket 连接
2. EventLoop 接口
EventLoop 用于处理连接的生命周期中所发生的事件,下图说明了 Channel、EventLoop、Thread 以及 EventLoopGroup 之间的关系
这些关系是:
- 一个 EventLoopGroup 包含一个或多个 EventLoop
- 一个 EventLoop 在它的生命周期内只和一个 Thread 绑定
- 所有由 EventLoop 处理的 IO 事件都将在它专有的 Thread 上被处理
- 一个 Channel 在它的生命周期内只注册一个 EventLoop
- 一个 EventLoop 可能会被分配到一个或多个 Channel
3. ChannelFuture 接口
Netty 所有的 IO 操作都是异步的,一个操作可能不会立即返回结果,因此我们需要一种用于在之后的某个时间点确定其结果的方法。Netty 提供了 ChannelFuture 接口,其 addListener() 方法注册一个 ChannelFutureListener,以便在某个操作完成时(无论是否成功0得到通知)
ChannelHandler 和 ChannelPipeline
1. ChannelHandler 接口
ChannelHandler 可以看作是负责处理入站和出站数据的应用程序逻辑的容器,例如将数据从一个格式转换为另一种格式,处理抛出的异常等等。ChannelInboundHandler 是一个经常使用的子接口,这种类型的 ChannelHandler 接收入站事件和数据,这些数据随后将被你的业务逻辑锁处理。当你想要给客户端发送响应时,也可以从 ChannelInboundHandler 冲刷数据,通常应用程序的业务逻辑通常驻留在一个或者多个 ChannelInboundHandler 中
2. ChannelPipeline 接口
ChannelPipeline 为 ChannelHandler 链提供了容器,并定义了用于在该链上传播入站和出站事件流的 API。当 Channel 被创建时,它会被自动地分配到它专属的 ChannelPipeline
ChannelHandler 安装到 ChannelPipeline 中的过程如下所示:
- 一个 ChannelInitializer 的实现被注册到了 ServerBootstrap 中
- 当 ChannelInitializer.initChannel() 方法被调用时,ChannelInitializer 将在 ChannelPipeline 中安装一组自定义的 ChannelHandler
- ChannelInitializer 将它自己从 ChannelPipeline 中移除
ChannelHandler 可以看作是处理往来 ChannelPipeline 事件(包括数据)的任何代码的通用容器,使事件流经过 ChannelPipeline 是 ChannelHandler 的工作,在应用程序的初始化或者引导阶段被安装。这些 ChannelHandler 接收事件、执行所实现的业务逻辑,并将数据传递给链中的下一个 ChannelHandler。它们的执行顺序由它们被添加的顺序所决定。实际上,ChannelPipeline 就是这些 ChannelHandler 的编排顺序
当 ChannelHandler 被添加到 ChannelPipeline 时,它会被分配一个 ChannelHandlerContext,其代表了 ChannelHandler 和 ChannelPipeline 之间的绑定,虽然这个对象可以被用于获取底层的 Channel,但它还是主要用于写出站数据
在 Netty 中有两种发送消息的方式,可以直接写到 Channel 中,也可以写到和 ChannelHandler 相关联的 ChannelHandlerContext 对象中。前一种方式将会导致消息从 ChannelPipeline 的尾端开始流动,后者将导致消息从 ChannelPipeline 中的下一个 ChannelHandler 开始流动
编码器和解码器
当你通过 Netty 发送或者接收一个消息时,就会发生一次数据转换。入站消息会被解码,即从字节转换成另一种格式,通常是一个 Java 对象。如果是出站消息,则会发生相反方向的转换,从当前格式被编码为字节。为此,Netty 为编码器和解码器提供了不同类型的抽象类,这些基类的名称将类似于 ByteToMessageDecoder 或 MessageToByteEncoder。对于一些特殊类型,可能还会有 ProtobufEncoder 和 ProtobufDecoder 这样的名称,用来支持 Google 的 Protocol Buffers
使用 Netty 提供的编码器/解码器,你会发现对于入站数据来说,channelRead 方法/事件已经被重写。对于每个从入站 Channel 读取的消息,将调用重写后的 channelRead 方法。随后,它将调用解码器提供的 decode() 方法,将已解码的字节转发给 ChannelPipeline 中的下一个 ChannelInboundHandler。出站消息是反过来的,编码器将消息转换为字节,并将它们转发给下一个 ChannelOutboundHandler
引导
Netty 的引导类为应用程序的网络层配置提供了容器,这涉及将一个进程绑定到某个指定的端口,或者将一个进程连接到另一个运行在某个指定主机的指定端口上的进程。通常我们把前面的用例称为引导一个服务器,后面的用例称为引导一个客户端。因此,有两种类型的引导:一种用于客户端(Bootstrap),而另一种(ServerBootstrap)用于服务器
两种类型的引导类区别如下:
ServerBootstrap 将绑定到一个端口,因为服务器必须要监听连接,而 Bootstrap 则是由想要连接到远程节点的客户端应用程序使用
引导一个客户端只需要一个 EventLoopGroup,但是一个 ServerBootstrap 则需要两个。因为服务器需要两组不同的 Channel,第一组只包含一个 ServerChannel,代表服务器自身已绑定到某个本地端口的正在监听的套接字,而第二组将包含所有已创建的用来处理传入客户端连接的 Channel
与 ServerChannel 相关联的 EventLoopGroup 将分配一个负责为传入连接请求创建 Channel 的 EventLoop。一旦连接被接受,第二个 EventLoopGroup 就会给它的 Channel 分配一个 EventLoop
Netty 框架学习 —— Netty 组件与设计的更多相关文章
- NetCore Netty 框架 BT.Netty.RPC 系列随讲 二 WHO AM I 之 NETTY/NETTY 与 网络通讯 IO 模型之关系?
一:NETTY 是什么? Netty 是什么? 这个问题其实百度上一搜一堆. 这是官方话的描述:Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个 ...
- Netty 框架学习 —— 引导
概述 前面我们学习了 ChannelPipeline.ChannelHandler 和 EventLoop 之后,接下来的问题是:如何将它们组织起来,成为一个可实际运行的应用程序呢?答案是使用引导(B ...
- Netty 框架学习 —— 编解码器框架
编解码器 每个网络应用程序都必须定义如何解析在两个节点之间来回传输的原始字节,以及如何将其和目标应用程序的数据格式做相互转换.这种转换逻辑由编解码器处理,编解码器由编码器和解码器组成,它们每种都可以将 ...
- Netty 框架学习 —— 第一个 Netty 应用
概述 在本文,我们将编写一个基于 Netty 实现的客户端和服务端应用程序,相信通过学习该示例,一定能更全面的理解 Netty API 该图展示的是多个客户端同时连接到一台服务器.客户端建立一个连接后 ...
- Netty 框架学习 —— EventLoop 和线程模型
EventLoop 接口 Netty 是基于 Java NIO 的,因此 Channel 也有其生命周期,处理一个连接在其生命周期内发生的事件是所有网络框架的基本功能.通常来说,我们使用一个线程来处理 ...
- Netty 框架学习 —— ByteBuf
概述 网络数据的基本单位总是字节,Java NIO 提供了 ByteBuffer 作为它的字节容器,但这个类的使用过于复杂.Netty 的 ByteBuf 具有卓越的功能性和灵活性,可以作为 Byte ...
- Netty 框架学习 —— 单元测试
EmbeddedChannel 概述 ChannelHandler 是 Netty 程序的关键元素,所以彻底地测试它们应该是你的开发过程中的一个标准部分,EmbeddedChannel 是 Netty ...
- Netty 框架学习 —— 预置的 ChannelHandler 和编解码器
Netty 为许多提供了许多预置的编解码器和处理器,几乎可以开箱即用,减少了在烦琐事务上话费的时间和精力 空闲的连接和超时 检测空闲连接以及超时对于释放资源来说至关重要,Netty 特地为它提供了几个 ...
- Netty 框架学习 —— 添加 WebSocket 支持
WebSocket 简介 WebSocket 协议是完全重新设计的协议,旨在为 Web 上的双向数据传输问题提供一个切实可行的解决方案,使得客户端和服务器之间可以在任意时刻传输消息 Netty 对于 ...
随机推荐
- 《剑指offer》刷题笔记
简介 此笔记为我在 leetcode 上的<剑指offer>专题刷题时的笔记整理. 在刷题时我尝试了 leetcode 上热门题解中的多种方法,这些不同方法的实现都列在了笔记中. leet ...
- linux中mysql连接不上,服务启动失败等问题解决
confluence问题解决方式 1)针对confluence访问页面报500与连接失败等问题 首先我们登陆部署confluence的服器 10.15.4.115 2)重启mysql服务,发现重启失败 ...
- ingress controller 和ingress使用实例
ingress controller安装 k8s集群版本:1.15+ 官方文档: https://kubernetes.github.io/ingress-nginx/ 创建基础配置 kubectl ...
- 基于MATLAB的手写公式识别(3)
基于MATLAB的手写公式识别 图像的膨胀化,获取边缘(思考是否需要做这种处理,初始参考样本相对简单) %膨胀 imdilate(dilate=膨胀/扩大) clc clear A1=imread(' ...
- POJ1236 强连通 (缩点后度数的应用)
题意: 一些学校有一个发送消息的体系,现在给你一些可以直接发送消息的一些关系(单向)然后有两个问题 (1) 问你至少向多少个学校发送消息可以让所有的学校都得到消息 (2) 问至少加多少条边 ...
- hdu4911 简单树状数组
题意: 给你一串数字,然后给你最多进行k次交换(只能交换相邻的)问交换后的最小逆序数是多少. 思路: 首先要知道的一个就是给你一个序列,每次只能交换相邻的位置,把他交换成一个递增序 ...
- 板载网卡MAC地址丢失后刷回方法[转]
部份客户在进行误操作后发现网卡MAC地址全部变成0,大部客户不知道如何重新将MAC地址写回去.就此问题我们介绍一下,希望可以帮到大家.修改MAC地址时,一定要在纯DOS环境下修改.目前使用U盘DOS引 ...
- 在 GitHub 学习,成长为自己想要的样子|HelloGitHub 访谈
万事开头难,我们经过长期的策划和筹备,终于推出了 HelloGitHub 采访系列「开源项目作者的访谈」.这是一个采访个人开源项目作者的栏目,内容侧重于开源项目作者与开源的故事. 我们深知想要做好一个 ...
- <JVM中篇:字节码与类的加载篇>01-Class字节码文件结构
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- 【python】Leetcode每日一题-直方图的水量(接雨水)
[python]Leetcode每日一题-直方图的水量(接雨水) [题目描述] 给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1. 上面是由数组 ...