您当前的位置:首页 > 电脑百科 > 网络技术 > 网络技术

物联网编程之通信框架-Netty(一)

时间:2020-03-16 13:22:26  来源:  作者:

1、引言


.NETty 是一个广受欢迎的异步事件驱动的JAVA开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。
本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件、整体架构,知其然且知其所以然,希望给大家在实际开发实践、学习开源项目方面提供参考。

2、相关资料


Netty源码在线阅读:

  • Netty-4.1.x地址是:http://docs.52im.net/extend/docs/src/netty4_1/
  • Netty-4.0.x地址是:http://docs.52im.net/extend/docs/src/netty4/
  • Netty-3.x地址是:http://docs.52im.net/extend/docs/src/netty3/

Netty在线API文档:

  • Netty-4.1.x API文档(在线版):http://docs.52im.net/extend/docs/api/netty4_1/
  • Netty-4.0.x API文档(在线版):http://docs.52im.net/extend/docs/api/netty4/
  • Netty-3.x API文档(在线版):http://docs.52im.net/extend/docs/api/netty3/

3、JDK 原生 NIO 程序的问题

JDK 原生也有一套网络应用程序 API,但是存在一系列问题,主要如下:

  • 1)NIO 的类库和 API 繁杂,使用麻烦:你需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。
  • 2)需要具备其他的额外技能做铺垫:例如熟悉 Java 多线程编程,因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的 NIO 程序。
  • 3)可靠性能力补齐,开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等。NIO 编程的特点是功能开发相对容易,但是可靠性能力补齐工作量和难度都非常大。
  • 4)JDK NIO 的 Bug:例如臭名昭著的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。官方声称在 JDK 1.6 版本的 update 18 修复了该问题,但是直到 JDK 1.7 版本该问题仍旧存在,只不过该 Bug 发生概率降低了一些而已,它并没有被根本解决。

4、Netty 的特点


Netty 对 JDK 自带的 NIO 的 API 进行了封装,解决了上述问题。
Netty的主要特点有:

  • 1)设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池;真正的无连接数据报套接字支持(自 3.1 起)。
  • 2)使用方便:详细记录的 Javadoc,用户指南和示例;没有其他依赖项,JDK 5(Netty 3.x)或 6(Netty 4.x)就足够了。
  • 3)高性能、吞吐量更高:延迟更低;减少资源消耗;最小化不必要的内存复制。
  • 4)安全:完整的 SSL/TLS 和 StartTLS 支持。
  • 5)社区活跃、不断更新:社区活跃,版本迭代周期短,发现的 Bug 可以被及时修复,同时,更多的新功能会被加入。

5、Netty 常见使用场景


Netty 常见的使用场景如下:

  • 1)互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。
  • 2)游戏行业:无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。

非常方便定制和开发私有协议栈,账号登录服务器,地图服务器之间可以方便的通过 Netty 进行高性能的通信。

  • 3)大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨界点通信,它的 Netty Service 基于 Netty 框架二次封装实现。
  • 4)物联网行业:基于Netty异步高性能事件驱动机制,开发与终端通信的Java后台服务程序已经不再是难事,已经有很多物联网企业选择Netty。

有兴趣的读者可以了解一下目前有哪些开源项目使用了 Netty的Related Projects:https://netty.io/wiki/related-projects.html

6、Netty 高性能设计


Netty 作为异步事件驱动的网络,高性能之处主要来自于其 I/O 模型和线程处理模型,前者决定如何收发数据,后者决定如何处理数据(重点理解这点)。
6.1I/O 模型

用什么样的通道将数据发送给对方,BIO、NIO 或者 AIO,I/O 模型在很大程度上决定了框架的性能。
【阻塞 I/O】:
传统阻塞型 I/O(BIO)可以用下图表示:

物联网编程之通信框架-Netty(一)

 

特点如下:

  • 每个请求都需要独立的线程完成数据 Read,业务处理,数据 Write 的完整操作问题。
  • 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。
  • 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费。

【I/O 复用模型】:

物联网编程之通信框架-Netty(一)

 

在 I/O 复用模型中,会用到 Select,这个函数也会使进程阻塞,但是和阻塞 I/O 所不同的是这两个函数可以同时阻塞多个 I/O 操作。
而且可以同时对多个读操作,多个写操作的 I/O 函数进行检测,直到有数据可读或可写时,才真正调用 I/O 操作函数。
Netty 的非阻塞 I/O 的实现关键是基于 I/O 复用模型,这里用 Selector 对象表示:

物联网编程之通信框架-Netty(一)

 

Netty 的 IO 线程 NioEventLoop 由于聚合了多路复用器 Selector,可以同时并发处理成百上千个客户端连接。
当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。
线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。
由于读写操作都是非阻塞的,这就可以充分提升 IO 线程的运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
一个 I/O 线程可以并发处理 N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞 I/O 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。
【基于 Buffer】:
传统的 I/O 是面向字节流或字符流的,以流式的方式顺序地从一个 Stream 中读取一个或多个字节, 因此也就不能随意改变读取指针的位置。
在 NIO 中,抛弃了传统的 I/O 流,而是引入了 Channel 和 Buffer 的概念。在 NIO 中,只能从 Channel 中读取数据到 Buffer 中或将数据从 Buffer 中写入到 Channel。
基于 Buffer 操作不像传统 IO 的顺序操作,NIO 中可以随意地读取任意位置的数据。

6.2线程模型


数据报如何读取?读取之后的编解码在哪个线程进行,编解码后的消息如何派发,线程模型的不同,对性能的影响也非常大。
【事件驱动模型】:
通常,我们设计一个事件处理模型的程序有两种思路:

  • 1)轮询方式:线程不断轮询访问相关事件发生源有没有发生事件,有发生事件就调用事件处理逻辑;
  • 2)事件驱动方式:发生事件,主线程把事件放入事件队列,在另外线程不断循环消费事件列表中的事件,调用事件对应的处理逻辑处理事件。事件驱动方式也被称为消息通知方式,其实是设计模式中观察者模式的思路。

以 GUI 的逻辑处理为例,说明两种逻辑的不同:

  • 1)轮询方式:线程不断轮询是否发生按钮点击事件,如果发生,调用处理逻辑。
  • 2)事件驱动方式:发生点击事件把事件放入事件队列,在另外线程消费的事件列表中的事件,根据事件类型调用相关事件处理逻辑。

这里借用 O'Reilly 大神关于事件驱动模型解释图:

物联网编程之通信框架-Netty(一)

 

主要包括 4 个基本组件:

  • 1)事件队列(event queue):接收事件的入口,存储待处理事件;
  • 2)分发器(event mediator):将不同的事件分发到不同的业务逻辑单元;
  • 3)事件通道(event channel):分发器与处理器之间的联系渠道;
  • 4)事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作。

可以看出,相对传统轮询模式,事件驱动有如下优点:

  • 1)可扩展性好:分布式的异步架构,事件处理器之间高度解耦,可以方便扩展事件处理逻辑;
  • 2)高性能:基于队列暂存事件,能方便并行异步处理事件。

【Reactor 线程模型】:
Reactor 是反应堆的意思,Reactor 模型是指通过一个或多个输入同时传递给服务处理器的服务请求的事件驱动处理模式。
服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程,Reactor 模式也叫 Dispatcher 模式,即 I/O 多了复用统一监听事件,收到事件后分发(Dispatch 给某进程),是编写高性能网络服务器的必备技术之一。
Reactor 模型中有 2 个关键组成:

  • 1)Reactor:Reactor 在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对 IO 事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;
  • 2)Handlers:处理程序执行 I/O 事件要完成的实际事件,类似于客户想要与之交谈的公司中的实际官员。Reactor 通过调度适当的处理程序来响应 I/O 事件,处理程序执行非阻塞操作。
物联网编程之通信框架-Netty(一)

 


取决于 Reactor 的数量和 Hanndler 线程数量的不同,Reactor 模型有 3 个变种:

  • 1)单 Reactor 单线程;
  • 2)单 Reactor 多线程;
  • 3)主从 Reactor 多线程。

可以这样理解,Reactor 就是一个执行 while (true) { selector.select(); …} 循环的线程,会源源不断的产生新的事件,称作反应堆很贴切。
篇幅关系,这里不再具体展开 Reactor 特性、优缺点比较,有兴趣的读者可以参考我之前另外一篇文章:《高性能网络编程(五):一文读懂高性能网络编程中的I/O模型》、《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》。
【Netty 线程模型】:
Netty 主要基于主从 Reactors 多线程模型(如下图)做了一定的修改,其中主从 Reactor 多线程模型有多个 Reactor:

  • 1)MainReactor 负责客户端的连接请求,并将请求转交给 SubReactor;
  • 2)SubReactor 负责相应通道的 IO 读写请求;
  • 3)非 IO 请求(具体逻辑处理)的任务则会直接写入队列,等待 worker threads 进行处理。

这里引用 Doug Lee 大神的 Reactor 介绍——Scalable IO in Java 里面关于主从 Reactor 多线程模型的图:

物联网编程之通信框架-Netty(一)

 


特别说明的是:虽然 Netty 的线程模型基于主从 Reactor 多线程,借用了 MainReactor 和 SubReactor 的结构。但是实际实现上 SubReactor 和 Worker 线程在同一个线程池中:

EventLoopGroup bossGroup = new NioEventLoopGroup();

EventLoopGroup workerGroup = new NioEventLoopGroup();

ServerBootstrap server = new ServerBootstrap();

server.group(bossGroup, workerGroup)

.channel(NIOServerSocketChannel.class)


上面代码中的 bossGroup 和 workerGroup 是 Bootstrap 构造方法中传入的两个对象,这两个 group 均是线程池:

  • 1)bossGroup 线程池则只是在 Bind 某个端口后,获得其中一个线程作为 MainReactor,专门处理端口的 Accept 事件,每个端口对应一个 Boss 线程;
  • 2)workerGroup 线程池会被各个 SubReactor 和 Worker 线程充分利用。

【异步处理】:
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
Netty 中的 I/O 操作是异步的,包括 Bind、Write、Connect 等操作会简单的返回一个 ChannelFuture。
调用者并不能立刻获得结果,而是通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果。
当 Future 对象刚刚创建时,处于非完成状态,调用者可以通过返回的 ChannelFuture 来获取操作执行的状态,注册监听函数来执行完成后的操作。
常见有如下操作:

  • 1)通过 isDone 方法来判断当前操作是否完成;
  • 2)通过 isSuccess 方法来判断已完成的当前操作是否成功;
  • 3)通过 getCause 方法来获取已完成的当前操作失败的原因;
  • 4)通过 isCancelled 方法来判断已完成的当前操作是否被取消;
  • 5)通过 addListener 方法来注册监听器,当操作已完成(isDone 方法返回完成),将会通知指定的监听器;如果 Future 对象已完成,则理解通知指定的监听器。

例如下面的代码中绑定端口是异步操作,当绑定操作处理完,将会调用相应的监听器处理逻辑:

serverBootstrap.bind(port).addListener(future -> {

if (future.isSuccess()) {

System.out.println(new Date() + ": 端口[" + port + "]绑定成功!");

} else {

System.err.println("端口[" + port + "]绑定失败!");

}

});


相比传统阻塞 I/O,执行 I/O 操作后线程会被阻塞住, 直到操作完成;异步处理的好处是不会造成线程阻塞,线程在 I/O 操作期间可以执行别的程序,在高并发情形下会更稳定和更高的吞吐量。



Tags:物联网编程   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1、引言 Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。 本文基于 Netty 4.1 展开介绍相关理论模型,使用场...【详细内容】
2020-03-16  Tags: 物联网编程  点击:(189)  评论:(0)  加入收藏
▌简易百科推荐
前言经过了多年的努力,在 6 月 6 号,IETF (互联网工程任务小组) 正式发布了 HTTP/3 的 RFC。HTTP 历史 1991 HTTP/1.1 2009 Google 设计了基于TCP的SPDY 2013 QUIC 2015 HTTP/2...【详细内容】
2022-07-15  Java机械师    Tags:HTTP/3   点击:(1)  评论:(0)  加入收藏
关于万维网的一点历史没有过去,就没有未来。要了解未来会发生什么,我们需要知道我们现在和以前拥有什么。因此,与其一下跳到web3.0的技术和示例上,我们需要了解 Web 1.0 的基本...【详细内容】
2022-07-05  木偶跳舞    Tags:Web 3.0   点击:(24)  评论:(0)  加入收藏
在刚刚拿到购买的CS10无线网关设备,应该如何开始使用呢?请看下面的几个步骤: Step1:首先我们找到产品包装内的一张带有初始WIFI名称和密码的贴纸,将它贴在产品的背面(以备未来使用...【详细内容】
2022-06-30  PLUS1软件教学频道    Tags:CS10   点击:(32)  评论:(0)  加入收藏
企业局域网内外网分离方案一些企事业单位出于安全考虑,需要做内外网分离。举例来说,需要达到如下的技术要求: 生产网、办公网、外网三网隔离。 启用网络准入,对非规定允许接入的...【详细内容】
2022-06-30  运维幼儿    Tags:内外网分离   点击:(31)  评论:(0)  加入收藏
在这个时代,我们至少有一半的重要信息都在手机上。无论是个人信息或是财务信息,还是敏感项目和工作机密,所有的这些都被我们驻留在手机上。现在越来越多的手机诈骗出现,这种第三...【详细内容】
2022-06-28  AirDroid    Tags:移动设备   点击:(26)  评论:(0)  加入收藏
最近各个方面的事情逐渐地恢复,继续写家庭网络实验室的文章。在考虑洁净和需求之后,我们就需要考虑家庭网络实验室的空间了。首先先亮一个观点——如果你真的想在家...【详细内容】
2022-06-28  iN在    Tags:家庭网络   点击:(29)  评论:(0)  加入收藏
背景:网络穿透互联是方便我们技术人员的一种工具,通过各种协议实现您想要的网络互联。家庭组网可以参照低成本电信家庭宽带架构网络拓扑今天,我们需要在这个基础上扩展网络应...【详细内容】
2022-06-27  应用技术    Tags:局域网互联   点击:(28)  评论:(0)  加入收藏
FTP是File Transfer Protocol(文件传输协议),用来进行服务器和客户端之间文件传输的协议。非常常用的服务,应用场景主要在设备间文件共享,服务程序发布,日志文件管理等方面。这里...【详细内容】
2022-06-27  影三分plus    Tags:FTP   点击:(37)  评论:(0)  加入收藏
一、后台确认监控/录像机在局域网内的IP地址如:192.168.1.158 ,在浏览器内输入后回车,即可进入监控/录像机WEB登录界面 二、输入用户名及密码进入WEB管理界面 三、如果进...【详细内容】
2022-06-23  一往直前的冲吧    Tags:监控   点击:(41)  评论:(0)  加入收藏
人在家中坐,网速突然断。相信这样的情况大家都不陌生。那么,怎么样才能在装维小哥上门前快速自助排查解决简单问题呢?相信这份攻略能够帮到你~ 一旦出现家中断网,而且在重启光猫...【详细内容】
2022-06-22  安利小丸子    Tags:网速   点击:(26)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条