netty知识总结

Posted better_hui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了netty知识总结相关的知识,希望对你有一定的参考价值。

目录

一、tcp & udp

二、tcp如何保证更可靠

1、确认应答和序列号

2、超时重传

3、流量控制

4、拥塞控制

三、滑动窗口

四、状态流转

五、粘包、拆包

MTU(Maximun Transmission Unit)

MSS(Maximun Segment Size)

1、引起拆包、粘包的原因

2、tcp解决方案

3、netty解决方案

六、同步、异步、阻塞、非阻塞

七、网络IO模型

八、BIO、NIO、AIO

九、select 、poll 、 epoll

1、链接数

2、轮询方式

3、数据copy

十、netty 优点

十一、netty的组件

十二、什么是netty

十三、为什么使用netty

十四、应用场景

十五、重要组件


一、tcp & udp

tcp : 面向连接 ;基于流 ;可靠的;仅支持一对一;首部开销20b;全双工可靠信道

udp:无连接;基于报文;不可靠;支持一对多、多对一、多对多通信;首部开销小8b;不可靠信道

二、tcp如何保证更可靠

1、确认应答和序列号

TCP传输时,将数据流进行编号,这就是序列号 ;可以用来应答、数据排序去重

每次接收方收到数据后,对川蜀坊进行应答,也就是发送ack报文

 

2、超时重传

TCP发出一段后,启动一个定时器,等待目标端ack报文,如不能及时收到确认,则重新发送报文

3、流量控制

tcp链接双方均有一个固定大小的缓冲空间,tcp接收端只允许发送端发送缓冲区能够接纳大小的数据。

当接收方来不及处理发送方数据时,能够提示发送方降低速率,防止包丢失

tcp流量控制协议是可变大小的滑动窗口协议

4、拥塞控制

当网络阻塞时,发送方继续重发,会加重网络阻塞,所以当出现阻塞时,应该控制发送方的速率。拥塞控制是为了控制网络的阻塞程度。

 

TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。

三、滑动窗口

滑动窗口是tcp流量控制的协议。假设我们每次发送一个数据包,然后就等待ack应答 ,这样会极大的影响传输效率,所以,我们把多个数据包达成一个package,一起发送出去,然后一起等待 。我们能够一起发送的数据量大小 , 就是窗口。

 

我们每次发送固定大小的窗口的数据 ,然后等待ack ,可行吗?答案是否定的。

窗口设置小了 : 需要频繁的接收数据的ack应答

窗口设置大了: 接收端处理不过来,会阻塞我们的网络。

所以我们需要一个动态的窗口:接收方来告诉我,可以处理多少数据 , 这就是提出窗口;发送方根据提出窗口和 已发送但是未确认的量 , 来计算可用窗口的大小。

我们可以把数据看做一条链 , 有一个可以向后滑动的窗口,框柱了 已发送待确认和允许发送的数据段

TCP的包可以分为四种状态

  • 已发送并且已经确认的包。

  • 已发送但是没有确认的包。

  • 未发送但是可以发送的包。

  • 不允许被发送的包。

零窗口 :当接收方提出窗口= 0 ,发送方只能停止发送。但是会建立一个零窗口定时探测器,向接收方询问窗口大小,当不在是0时 , 就可以继续发送了。

四、状态流转

LISTEN:等待从任何远端TCP 和端口的连接请求。
​
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
​
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
​
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
​
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
​
FIN_WAIT_2:等待远端TCP 的连接终止请求。
​
CLOSE_WAIT:等待本地用户的连接终止请求。
​
CLOSING:等待远端TCP 的连接终止请求确认。
​
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
​
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
TIME_WAIT 两个存在的理由:
          1.可靠的实现tcp全双工连接的终止;
          2.允许老的重复分节在网络中消逝。
​
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)

五、粘包、拆包

tcp是流协议,本身是无界限的。tcp会根据实际情况划分发送,一个完整的数据包可能拆分成多个,也可以整合成一个进行发送,这就是拆包、粘包

MTU(Maximun Transmission Unit)

最大传输单元,在数据链路层中,规定MTU大小,以太网 设置为1500字节

MSS(Maximun Segment Size)

最大保温段 , MSS = MTU - IP首部(20)- TCP首部(20) = 1460

1、引起拆包、粘包的原因

1、应用程序写入的数据 超过了套接字缓存大小 , 发生拆包

2、应用程序写入的数据小于套接字缓存,缓存会整合多个数据,统一发送到网络上,发生粘包

3、接收方法不能即时读取套接字缓存区数据,发生粘包

2、tcp解决方案

1、消息定长

2、分隔符

3、消息头,规定数据长度

3、netty解决方案

1、FixedLengthFrameDecoder 消息定长

2、LineBasedFrameDecoder 换行符 和 DelimiterBasedFrameDecoder (用户自定义风格福)

3、LengthFieldBasedFrameDecoder 数据包中添加一个长度的字段

4、自定义编码、解码器

六、同步、异步、阻塞、非阻塞

  1. 同步,就是我调用一个功能,该功能没有结束前,我死等结果。

  2. 异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)

  3. 阻塞,就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。

  4. 非阻塞,就是调用我(函数),我(函数)立即返回,通过select通知调用者

同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞

阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回

七、网络IO模型

八、BIO、NIO、AIO

1、BIO , 同步且阻塞 , 一个请求一个线程,对服务器要求高,适用于连接数比较小且固定的架构,开发难度小

2、NIO,同步非阻塞 ,客服端的链接请求注册到多路复用器上,多路复用器轮询到有链接IO时,转给一个线程处理,自己继续阻塞等待,jdk1.4开始支持

3、AIO ,异步非阻塞,客户端的IO请求由内内核理完成,然后通知业务线程处理,适用于连接数多 且 链接较长的架构。jdk7 开始支持

九、select 、poll 、 epoll

1、链接数

select : 1024个 , 单个进程能打开的最大连接数 有FD_ZETSIZE 决定

poll : 没有上限,采用链表的方式

epoll : 链接数有上限,但是很大,1G内存支持10万的链接

2、轮询方式

select : 普通轮询 , 当连接数过大时,性能较差

poll : 同上

epoll : 采用回调的方式 , 链接的socket注册到epoll上 , 当有数据读写时,调用callBack

3、数据copy

select: 内核空间拷贝至用户空间 ,非常耗时

poll : 同上

epoll : 内核空间和用户空间 共享一块内存空间,相当于是零拷贝

十、netty 优点

NIO:

1、nio类库、api学习成本高,复杂

2、失败重试、数据丢失、拆包粘包等问题

3、selectk空轮训,内存飚增

netty:

1、架构设计优雅简单,耦合度低,底层模型可以使用不同网络协议

2、提供多种标准协议、安全、编码解码的支持

3、降低了NIO使用难度

4、很多开源框架都在使用,dubbo /rocketmq/spark

5、零拷贝、统一的api、标准可扩展的时间模型

十一、netty的组件

1、channel

2、buffer

3、EventLoop

4、ChannelHandler 和 ChannelPipeline

5、Bootstrap 和 ServerBootstrap

十二、什么是netty

1、netty是基于java nio(IO多路复用)的网络通信框架 ,极大的简化了TCP、UDP套接字服务的网络编程, 并且性能与安全性、使用性上更好。

2、特点:采用的reactor线程模型,是异步非阻塞、基于事件驱动、高性能、高可靠性和高定制型

3、支持多种协议、多种粘包拆包及二次编码机制。

4、使用范围广泛,比如dubbo/rocketMQ , Elasticsearch/gRPC等等

十三、为什么使用netty

1、简单易用,为我们屏蔽jdk自带的java nio的复杂度。

2、优秀的线程模型 reactor , 性能高 ,且零维护

3、功能强大,预置了多种编解码器,支持多种主流协议

4、高定制性,通过ChannelHandler 对通信框架进行灵活扩展

5、安全性高,有完整的SSL/TLS等支持

6、社区活动、网上教程多

7、使用广泛,在互联网、大数据、网络游戏等领取广泛应用,且满足商业标准

十四、应用场景

理论上NIO可以做的事情,使用netty都可以做。

1、作为RPC框架的网络通信工具:DUBBO、GRPC

2、用作HTTP服务器,目前我们常见的web服务器都是基于toncat或者jetty的 , 是基于serlet的 , NIO支持更底层的TCP协议,所以也可以用作支撑HTTP服务器,目前netty 就是http的协议支持。

3、即时的通讯系统,比如聊天工具 或者 聊天室,这块开源项目比较多的

4、消息推送系统。比如rocketMQ

十五、重要组件

1、bootstrap / serverbootstrap

bootstrap是netty的引导程序,采用了构造者模式,包含了线程组、通道channel、handler等配置信息。

引导netty的启动:

1、new NioEventLoop的构造方法里打开了一个多路复用器

2、serverBootstrap.bind()

2.1、创建一个ServerSocketChannel (initAndRegister())

2.2、绑定一个端口,先注册0事件 ,因为这时 项目还未完全启动

AbstractChannel对象的

selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);

2.3、真正的绑定 DefaultChannelPipeline.HeadContext -> AbstractChannel.Head

javaChannel().bind(localAddress, config.getBacklog());

ServerBootstrapAcceptor请求接收器,将boss线程接收到的链接请求封装转发给worker线程

public void channelRead(ChannelHandlerContext ctx, Object msg) {
    try {
        childGroup.register(child).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    forceClose(child, future.cause());
                }
            }
        });
    } catch (Throwable t) {
        forceClose(child, t);
    }
}

2、nioEventLoopGroup/nioEventLoop

netty的线程池和执行线程。

nioEventLoopGroup : 提供了创建、获取nioEventLoop、注册channel的方法。

nioEventLoop : 我们可以看做是线程的扩展,该对象主要负责监听网络事件 并调用事件处理器进行相关的操作。

3、channel

channel接口是netty 对网络操作的抽象 , 包含了基本的IO操作,如bind()/connet()/read()/write()等 , 其主要实现如下:

NioserverSocketChannel , 对应 java nio的 ServerSocketChannel

NioSocketChannel , 对应 java nio的 SocketChannel

4、channelFuture

netty是异步非阻塞 , 我们在发起调用后 , 有可能不能立刻得到我们期待的结果, 所以我们通过channelFuture.addListener ,添加一个回调。

另外我们还可以通过sync , 是的异步非阻塞变为同步阻塞式调用

5、channelPipeline

channelPipeline是channelHandler的双向链表,提供了一个容器定义并处理流转与处理器链上的channel。

一个channel只能绑定于一个channelPipeline , 也就只能在此容器内流转 ,局部范围内是串行的,没有线程安全问题

channelPipeline 定义了handler的head和tail , 可以沿着责任链依次处理。

6、channelHandler

是netty消息的具体处理器,负责处理连接、读、写等操作。

十三、高性能

基于I/O多路复用模型

零拷贝

基于NIO的Buffer

基于内存池的缓冲区重用机制

无锁化的串行设计理念

I/O操作的异步处理

提供对protobuf等高性能序列化协议支持

可以对TCP进行更加灵活地配置

以上是关于netty知识总结的主要内容,如果未能解决你的问题,请参考以下文章

netty知识总结

netty知识总结

Netty知识点总结

2021大厂Java社招最全面试题,最全Java知识总结

线程学习知识点总结

12.netty中tcp粘包拆包问题及解决方法