IO与Netty了解一下!网络通信框架是这样构成的!

Posted 厦门安胜网络科技有限公司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO与Netty了解一下!网络通信框架是这样构成的!相关的知识,希望对你有一定的参考价值。


随着互联网应用对高并发、高可用的要求越来越高,传统的垂直架构由于其自身的局限性逐渐被分布式、弹性伸缩的微服务架构替代。


微服务将单体应用拆分为多个独立的微服务应用,每个应用独立运行,每个服务间通过远程调用(RPC)进行通信,此时高性能的通信方式就显得尤为重要,实现RPC通信的底层框架Netty由于其稳定性、拓展性以及框架成熟度的优秀表现,在RPC框架领域应用广泛,著名的Hadoop、Dubbo、RocketMQ等框架都使用了Netty作为其网络通信的底层框架。


Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),它的并发性能得到了很大提高。接下来,ISEC实验室的林老师带大家了解下BIO与NIO的区别。


BIO (blocking io)

BIO即传统IO,是一种同步阻塞的通信模式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。应用程序在获取网络数据的时候,如果网络传输数据很慢,那么程序就一直等着,直到传输完毕为止。 


采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,每处理完成后,通过输出流返回应答给客户端,线程销毁。即典型的请求——应答通信模型。


1

Server端


IO与Netty了解一下!网络通信框架是这样构成的!

图1

IO与Netty了解一下!网络通信框架是这样构成的!

图2


2

Client端


IO与Netty了解一下!网络通信框架是这样构成的!

图3


这种处理方式在高并发的情况下,会创建出大量的线程,以至于最终耗尽资源,无法对外服务。所以传统的BIO线程模型,在现代情景的互联网应用中无法作为底层的通信模型进行使用。


NIO (non-blocking io)

NIO也称为New IO,是一种同步非阻塞的通信模式,NIO 相对于BIO来说是一大进步。客户端和服务器之间通过Channel通信,NIO可以在Channel进行读写操作,这些Channel都会被注册在Selector多路复用器上。Selector通过一个线程不停的轮询这些Channel,找出已经准备就绪的Channel执行IO操作。NIO 通过一个线程轮询,再基于轮询到的事件进行处理,不需要再为每个连接单独开个线程处理,从而以较高的资源复用率处理成千上万个客户端的请求,这就是非阻塞NIO的特点。


NIO的三大核心为Selector(选择器),Buffer(缓冲区),Channel(通道)。


▲缓冲区Buffer

它是NIO与BIO的一个重要区别。BIO是将数据直接写入或读取到Stream对象中,而NIO的数据操作都是在缓冲区进行的。缓冲区实际上也是一个数组,通常是一个字节数组(ByteBuffer),这个数组为缓冲区提供了数据的访问读写等操作属性,如位置、容量、上限等概念。(ByteBuffer由于只有一个位置指针处理读写操作,因此每次读写的时候都需要额外调用flip()将指针复位,否则功能将出错)



通道Channel

和流不同,通道是双向的。通道分为两大类:一类是网络读写(SelectableChannel),一类是用于文件操作(FileChannel),我们使用的SocketChannel和ServerSocketChannel都是SelectableChannel的子类。最关键的是channel有多种状态位,可以与selector结合起来,方便selector去识别。


选择器(多路复用器)Selector

是NIO编程的基础,非常重要,提供选择已经就绪的任务的能力。当Channel注册到选择器后,Selector会分配给每个通道一个key值。Selector会不断地轮询注册在其上的Channel,如果某个Channel处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以取得就绪的Channel集合,从而进行后续的IO操作。


1

Server端


IO与Netty了解一下!网络通信框架是这样构成的!

图4


IO与Netty了解一下!网络通信框架是这样构成的!

图5


IO与Netty了解一下!网络通信框架是这样构成的!

图6


IO与Netty了解一下!网络通信框架是这样构成的!

图7


2

Client端


IO与Netty了解一下!网络通信框架是这样构成的!

图8


为什么选择Netty

Netty是基于Java NIO的网络应用框架,使用Netty可以快速开发网络应用,例如服务器和客户端的协议。Netty提供了一种新的方式来开发网络应用,使得它很容易使用和有很强的扩展性。Netty内部的实现是复杂的,但是Netty提供了简单易用的API从网络处理代码中解耦业务逻辑。


Netty的优点有:

1.相较于JDK原生的NIO提供的API,Netty的API使用简单,开发门槛低;


2.功能强大,预置了多种编解码功能,支持多种协议开发;


3.定制能力强,可以通过ChannelHandler进行扩展;


4.性能高,对比其它NIO框架,Netty综合性能最优;


5.经历了大规模的应用验证。在互联网、大数据、网络游戏、企业应用、电信软件得到成功,很多著名的框架通信底层就用了Netty,比如Dubbo;


6.稳定,修复了已经发现的NIO Bug。


Netty的使用


步骤:

1.创建两个NioEventLoopGroup实例,NioEventLoopGroup是个线程组,它包含了一组NIO线程,专门用于网络事件处理。这里创建两个的原因是一个用于服务端接收客户端的连接,另一个用于进行SocketChannel的网络读写;


2.创建一个ServerBootstrap对象,它是Netty用于启动NIO服务端的辅助启动类。配置Netty的一系列参数,例如将两个NIO线程组当作入参传递到ServerBootstrap中,设置创建的Channel,接受传出数据的缓存大小等;


3.创建一个实际处理数据的类Channellnitalizer,绑定IO事件的处理类ChannelHandler,进行初始化的准备工作,比如设置接受传出数据的字符、格式以及实际处理数据的接口;


4.绑定接口,执行同步阻塞方法;


5.最后调用NIO线程组的shutdownGracefully进行优雅退出,它会释放跟shutdownGracefully相关联的资源。


1

Server端


IO与Netty了解一下!网络通信框架是这样构成的!

图9


ChannelHandler类似于Servlet的Filter过滤器,负责对IO事件或者IO操作进行拦截和处理,它可以选择性地拦截和处理自己感兴趣的事件。Netty提供了ChannelHandlerAdapter基类,如果用户ChannelHandler关心某个事件,只需要覆盖ChannelHandlerAdapter对应的方法即可,对于不关心的,可以直接继承使用父类的方法,这样子类的代码就会非常简洁和清晰。


 ChannelHandlerContext对象提供了许多操作,这里我们调用了write(Object)方法来逐字地把接受到的消息写入。ctx.write(Object)方法不会使消息写入到通道上,他被缓冲在了内部,你需要调用ctx.flush()方法来把缓冲区中数据强行输出。或者你可以用更简洁的cxt.writeAndFlush(msg)以达到同样的目的。


还有ByteBuf是一个引用计数对象,这个对象需要调用release()方法来释放。


2

ServerHandler


IO与Netty了解一下!网络通信框架是这样构成的!

图10


3

Client端


IO与Netty了解一下!网络通信框架是这样构成的!

图11


4

ClientHandler


IO与Netty了解一下!网络通信框架是这样构成的!

图12


TCP拆包和粘包的问题解决

在基于流的传输里比如TCP/IP,接收到的数据会先被存储到一个socket接收缓冲里。不幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列。即使你发送了2个独立的数据包,操作系统也不会作为2个消息处理,而仅仅是作为一连串的字节而言。因此这是不能保证你远程写入的数据就会准确地读取。举个例子,让我们假设操作系统的TCP/TP协议栈已经接收了3个数据包:

IO与Netty了解一下!网络通信框架是这样构成的!

图13


但是基于流传输的性质,在你的应用程序读取数据的时候很可能会被分成下面的片段。

IO与Netty了解一下!网络通信框架是这样构成的!

图14


因此,一个接收方不管他是客户端还是服务端,都应该把接收到的数据整理成一个或者多个更有意思并且能够让程序的业务逻辑更好理解的数据。在上面的例子中,接收到的数据应该被构造成下面的格式:

IO与Netty了解一下!网络通信框架是这样构成的!

图15


解决方式

1.消息定长,例如每个报文的大小固定为200个字节,如果不够,空位补空格。

IO与Netty了解一下!网络通信框架是这样构成的!

图16


2.在包尾部增加特殊字符进行分割,例如加”$”

IO与Netty了解一下!网络通信框架是这样构成的!

图17


3.将消息分为消息头和消息体,消息头中包含表示信息的总长度(或者消息体长度)的字段。


用POJO代替ByteBuf

在ChannelHandler中使用POJO的优点是显而易见的; 处理程序将从ByteBuf中提取信息的代码分离出来,使程序更易维护和可重用。


下面的例子通过MarshallingCodeCFactory工厂类创建了MarshallingDecoder解码器、MarshallingEncoder编码器,并添加到ChannelPipeline中。


1

POJO类


IO与Netty了解一下!网络通信框架是这样构成的!

图18


2

在ChannelPipeline加上编解码的Handler


IO与Netty了解一下!网络通信框架是这样构成的!

图19

  

3

 MarshallingCodeCFactory工厂类

  

IO与Netty了解一下!网络通信框架是这样构成的!

图20


IO与Netty了解一下!网络通信框架是这样构成的!

图21


IO与Netty了解一下!网络通信框架是这样构成的!

互了个动

小伙伴们,

本期内容到这里就结束啦,

你get到了吗?IO与Netty了解一下!网络通信框架是这样构成的! 


欢迎大家于文末留言

分享你的宝贵见解、

疑问、补充~


与ISEC实验室大神互动的机会来啦!

速速行动起来撒!


安胜作为国内领先的网络安全类产品及服务提供商,秉承“创新为安,服务致胜”的经营理念,专注于网络安全类产品的生产与服务;以“研发+服务+销售”的经营模式,“装备+平台+服务”的产品体系,在技术研究、研发创新、产品化等方面已形成一套完整的流程化体系,为广大用户提供量体裁衣的综合解决方案!


ISEC实验室作为公司新技术和新产品的预研基地,秉承“我的安全,我做主”的理念,专注于网络安全领域前沿技术研究,提供网络安全培训、应急响应、安全检测等服务。


2018年

承担全国两会网络安全保障工作。

2017年

承担全国两会网络安全保障工作;

完成金砖“厦门会晤”保障工作;

完成北京“一带一路”国际合作高峰论坛网络安全保障;

承担中国共产党第十九次全国代表大会网络安全保障。

承担第四届世界互联网大会。

2016年

承担全国两会网络安全保障工作;

为贵阳大数据与网络安全攻防演练提供技术支持;

承担G20峰会的网络安保工作;

承担第三届世界互联网大会。

2015年

承担第二届世界互联网大会。

不忘初心、砥砺前行;未来,我们将继续坚守、不懈追求,为国家网络安全事业保驾护航!




以上是关于IO与Netty了解一下!网络通信框架是这样构成的!的主要内容,如果未能解决你的问题,请参考以下文章

Netty的框架构成

Netty4 Channel 概述(通道篇)

RPC&Netty 学习之路

如何用Netty写一个高性能的分布式服务框架?

Netty是什么?

Netty框架之深入了解NIO核心组件