1. Netty 介绍

  Netty 是一个无阻塞的输入/输出(NIO)框架,它使开发低级网络服务器和客户端变得相对简单。Netty为需要在套接字级别上工作的开发人员提供了令人难以置信的强大功能,例如,在开发客户端和服务器之间的自定义通信协议时。它支持SSL / TLS,具有阻塞和非阻塞统一API,以及灵活的线程模型。它又快又高效。

  Netty 异步、非阻塞 I/O 模型是为高度可扩展的体系结构设计的,与类似的其他阻塞模型相比,它可能允许更高的吞吐量。基本上,非阻塞服务器在单个线程上异步运行所有请求(没有函数会“阻塞”事件循环)。这与阻塞服务器模型形成对比,后者通常在单独的线程上运行每个请求。通过不必在负载增加时切换线程创建新线程,非阻塞模型可以减少开销,并在流量增加时更快地进行扩展。

  Netty 的核心组件:Channel、回调、Future、事件和ChannelHandler。

2. Channel 通道

  Channel 与网络套接字或能够进行 I/O 操作(例如读取,写入,连接和绑定)的组件的枢纽。 

  Channel 为用户提供:

  • 通道的当前状态(例如,它是否打开?是否已连接?)

  • 通道的 ChannelConfig 配置参数(例如,接收缓冲区大小)

  • 通道支持的 I/O 操作(例如,读取,写入,连接和绑定)

  • 处理所有与该通道关联的I/O事件和请求的 ChannelPipeline

  

  Netty 的 Channel 接口的一些类型(Java类图):

  

  

  Channel 主要衍生有这几个类型的接口:

  • Http2StreamChannel:支持 HTTP/2 协议的 Channel。

  • ServerChannel:一个接收新连接然后创建子Channel的Channel组件, ServerSocketChannel 就是一个很好的例子, ServerSocketChannel 接受连接,然后创建出 SocketChannel。

  • SctpChannel:一个处理 SCTP/IP 协议(流控制传输协议 (Stream Control Transmission Protocol))的 Channel。

  • DatagramChannel:一个处理 UDP/IP 协议的 Channel。

  • DuplexChannel:一个拥有两个端点并能在每个端点独立关闭的全双工Channel。

  Channel 的一些特性

  1)所有I / O操作都是异步的

  Netty中的所有I / O操作都是异步的。这不意味着任何I / O调用都将立即返回,不能保证所请求的I / O操作已在调用结束时完成。相反,你将获得返回一个ChannelFuture实例,该实例将在请求的I / O操作成功,失败或取消时通知你。

  2)Channel是分层的

  Channel可以有一个parent(父级},具体取决创建方式。例如,ServerSocketChannel接受的SocketChannel将返回ServerSocketChannel作为其在parent上的父级。层次结构的语义取决于Channel所属的transport实现。

  3)向下访问特定于传输的操作

  某些传输会公开特定于传输的其他操作。将 Channel 向下转换为子类型以调用此类操作。例如,对于旧的 I/O 数据报传输,DatagramChannel提供了多播加入/离开操作。

  4)释放资源

  一旦完成Channel,调用 #close 或 #close(ChannelPromise)释放所有资源很重要。这样可以确保以适当的方式释放所有资源,即文件句柄。

  那么 Channel 在什么时候创建?

  Netty 服务端引导类  ServerBootstrap#bind()  方法中的  doBind()  方法调用  initAndRegister() ,方法具体内容再移步到父类  AbstractBootstrap#initAndRegister  方法处,创建是有 Channel 工厂来创建的,类型是由 Netty 的  BootStrap  实例化时指定的 Channel 类型,例如 NioSocketChannel.class。

 1 /**
2 * Create a new {@link Channel} and bind it.
3 */
4 public ChannelFuture bind(SocketAddress localAddress) {
5 validate();
6 if (localAddress == null) {
7 throw new NullPointerException("localAddress");
8 }
9 return doBind(localAddress);
10 }

   doBind(localAddress); 具体方法:

 1     private ChannelFuture doBind(final SocketAddress localAddress) {
2 final ChannelFuture regFuture = initAndRegister();
3 final Channel channel = regFuture.channel();
4 if (regFuture.cause() != null) {
5 return regFuture;
6 }
7
8 if (regFuture.isDone()) {
9 // At this point we know that the registration was complete and successful.
10 ChannelPromise promise = channel.newPromise();
11 doBind0(regFuture, channel, localAddress, promise);
12 return promise;
13 } else {
14 // Registration future is almost always fulfilled already, but just in case it's not.
15 final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
16 regFuture.addListener(new ChannelFutureListener() {
17 @Override
18 public void operationComplete(ChannelFuture future) throws Exception {
19 Throwable cause = future.cause();
20 if (cause != null) {
21 // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
22 // IllegalStateException once we try to access the EventLoop of the Channel.
23 promise.setFailure(cause);
24 } else {
25 // Registration was successful, so set the correct executor to use.
26 // See https://github.com/netty/netty/issues/2586
27 promise.registered();
28
29 doBind0(regFuture, channel, localAddress, promise);
30 }
31 }
32 });
33 return promise;
34 }
35 }

   initAndRegister() 方法通过 ChannelFactory 创建 NioServerSocketChannel。

 1     final ChannelFuture initAndRegister() {
2 Channel channel = null;
3 try {
4 channel = channelFactory.newChannel();
5 init(channel);
6 } catch (Throwable t) {
7 if (channel != null) {
8 // channel can be null if newChannel crashed (eg SocketException("too many open files"))
9 channel.unsafe().closeForcibly();
10 // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
11 return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
12 }
13 // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
14 return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t);
15 }
16
17 ChannelFuture regFuture = config().group().register(channel);
18 if (regFuture.cause() != null) {
19 if (channel.isRegistered()) {
20 channel.close();
21 } else {
22 channel.unsafe().closeForcibly();
23 }
24 }
25
26 // If we are here and the promise is not failed, it's one of the following cases:
27 // 1) If we attempted registration from the event loop, the registration has been completed at this point.
28 // i.e. It's safe to attempt bind() or connect() now because the channel has been registered.
29 // 2) If we attempted registration from the other thread, the registration request has been successfully
30 // added to the event loop's task queue for later execution.
31 // i.e. It's safe to attempt bind() or connect() now:
32 // because bind() or connect() will be executed *after* the scheduled registration task is executed
33 // because register(), bind(), and connect() are all bound to the same thread.
34
35 return regFuture;
36 }

  Channel 的四个状态:

状态 描述
channelUnRegistered 频道创建后但未注册到一个EventLoop
channelRegistered 频道注册到一个EventLoop
channelActive channel的活动的(连接到了它的remote peer),现在可以接收和发送数据了
channelInactive channel没有连接到远程对等

  Channel 的正常生命周期如下图,当这些状态变化出现,对应的事件将会生成,这样与 ChannelPipeline 中的 ChannelHandler 的交互能够及时响应:

参考:Netty源码分析之一揭开Bootstrap神秘的红盖头(客户端)Netty分析--Channel的创建

Netty:Netty的介绍以及它的核心组件(一)—— Channel的更多相关文章

  1. Netty:Netty的介绍以及它的核心组件(二)—— ChannelFuture与回调

    Callback 回调 一个 Callback(回调)就是一个方法,一个提供给另一个的方法的引用. 这让另一个方法可以在适当的时候回过头来调用这个 callback 方法.Callback 在很多编程 ...

  2. Netty重要概念介绍

    Netty重要概念介绍 Bootstrap Netty应用程序通过设置bootstrap(引导)类开始,该类提供了一个用于网络成配置的容器. 一种是用于客户端的Bootstrap 一种是用于服务端的S ...

  3. 5. 彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Java NIO的核心组件之一--Channel. 思维转变 首先, ...

  4. netty05(netty的一些介绍)

    netty的一些理论 netty是一个异步事件驱动的网络应用框架(NIO框架),所有IO操作都是异步非阻塞的,NIO是对IO的一个补充 用于开发客户端和服务器的通信(TCP/UDP)长短连接 nett ...

  5. [Netty] - Netty IN ACTION(导言)

    最近没什么事儿做,刚好看到有需要网络编程的知识,java中有NIO和IO两种不同的方式,但是NIO的编写比较麻烦,刚好找到一个成熟的网络框架Netty.接下来的一个月就准备将Netty IN ACTI ...

  6. Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler

    Netty 使用异步事件驱动(Asynchronous Event-Driven)的应用程序范式,因此数据处理的管道(ChannelPipeLine)是经过处理程序(ChannelHandler)的事 ...

  7. Netty——基本使用介绍

    https://blog.csdn.net/haoyuyang/article/details/53243785 1.为什么选择Netty 上一篇文章我们已经了解了Socket通信(IO/NIO/AI ...

  8. netty核心组件之channel、handler、ChannelHandlerContext、pipeline

    channel介绍: netty中channel分为NioServerScoketChannel和NioSocketChannel,分别对应java nio中的ServerScoketChannel和 ...

  9. Java NIO框架Mina、Netty、Grizzly介绍与对比(zz)

    Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...

随机推荐

  1. 【第十四篇】- Maven 自动化构建之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 自动化构建 自动化构建定义了这样一种场景: 在一个项目成功构建完成后,其相关的依赖工程即开始构建,这样可以保证其依赖项目的稳定. 比如一个团队正在开发一个项目 bus-core-api, ...

  2. Zookeeper Acl权限 超级用户权限 怎么跳过ACL密码/账户验证

    Zookeeper的一个节点不知道什么原因无法删除了,查看日志发现是没有权限, 我们之前使用ACL进行Zookeeper节点的权限管理. 可以解决以下三种但不限于以下三种问题: 1.在设置Acl权限时 ...

  3. Linux上安装服务器监视工具,名为pyDash。

    pyDash – A Web Based Linux Performance Monitoring Tool 你可以通过以下命令来判断是否已安装: pip --version # Python2.x ...

  4. C++课后习题

    一.设计一个类people,有保护数据成员:age(年龄,整型),name(姓名,string),行为成员:两个构造函数(一个默认,另一个带参数):析构函数:void setValue(int m, ...

  5. php_excel导出

    1.下载PHPExcel工具 2.解压后放置位置:ThinkPHP\Extend\Vendor\PHPExcel\PHPExcel.php. 3.Common.php代码 public functio ...

  6. Appium Capability使用进阶

  7. springBoot 基础入门

    来处:是spring项目中的一个子项目 优点  (被称为搭建项目的脚手架)         减少一切xml配置,做到开箱即用,快速上手,专注于业务而非配置     从创建项目上: -- 快速创建独立运 ...

  8. css 圆形脉冲动画

    需求: 项目需要在3D场景增加动画按钮,直接添加到场景时 当场景过大的时候 .加载比较麻烦 因在找资料时发现这玩意居然要付费.故做此记录, 效果: 参考: 1.https://www.jiangwei ...

  9. 「含源码」关于NXP IMX8 Mini的图形开发指南(GPU)案例分享!

    前言 Graphical Demo框架提供了对平台相关依赖的抽象.Graphical应用的通用封装,如模型加载.纹理加载.着色器编译等,以及其它一些通用的应用逻辑处理的封装,使得使用框架的开发人员(以 ...

  10. P4320-道路相遇,P5058-[ZJOI2004]嗅探器【圆方树,LCA】

    两题差不多就一起写了 P4320-道路相遇 题目链接:https://www.luogu.com.cn/problem/P4320 题目大意 \(n\)个点\(m\)条边的一张图,\(q\)次询问两个 ...