异步io框架 netty 网络通信底层框架

一、概述

异步io框架,做网络通信的基础底层框架。被很多其他框架所使用,比如dubbo。

io分类

java共支持三种io模式,bio,nio,aio

bio就是最普通的io,阻塞同步io。客户端每发一个连接请求,服务端都要专门起一个线程去处理。

nio是同步非阻塞io,服务端起一个线程维护一个selector,这个selector去处理多个客户端的连接请求。

aio是异步非阻塞

二、nio

三大核心

selector,channel,buffer

一个线程对应一个selector,一个selector对应多个channel,一个channel对应一个buffer。

selector去处理哪个channel,是由事件决定的。

channel,buffer都是双向的。
在这里插入图片描述

缓冲区buffer

nio在selector和socket(程序)之间有channel和buffer,通过channel就可以进行数据传输。但正是有了缓冲区,才可以做到非阻塞。由buffer去和channel交互。

所谓缓冲区底层是数组,有各种buffer,shortbuffer,intbuffer,bytebuffer,longbuffer,不同的buffer存不同的数据类型。最常用的是bytebuffer。

通道channel

channel特性:

  1. 同时读写
  2. 异步读写

选择器selector

基本概念

Java的Nio,用非阻塞的io方式,用一个线程去处理多个客户端的连接,就会使用到Selector(选择器)

处理多个客户端连接的方式

多个channel以事件的方式注册到同一个selector,如果有事件发生,便获取事件,针对每个事件做对应的处理。以此来做到一个线程管理多个连接(实质是一个selector管理多个channel通道)。

三、AIO

I/O编程两种模式

在进行 I/O 编程中,常用到两种模式:Reactor和 Proactor,两个词顾名思义,reactor,是反应,而proactor,就是在反应前就反应。说白了,aio希望当有有效请求时才启动线程。(和nio对比,nio是一直有一个线程在轮询)

但目前aio并没有得到广泛使用,而netty也是基于nio的。

四、netty

原生nio存在的问题

  1. nio的类库以及api繁杂,使用麻烦
  2. 需要对多线程和网络编程很熟
  3. 开发难度以及工作量都很大
  4. 存在bug,如epoll bug

netty的优点

对原生nio进行了封装,便捷好用

目前稳定的是4.x版本

netty高性能架构设计

Reactor模式

单reactor单线程

负责监听事件和分发任务的线程是一个,处理任务的线程还是一个

单reactor多线程

负责监听事件和分发任务的线程是一个,处理任务的线程是多个

主从reactor多线程

负责监听事件和分发任务的线程是多个,处理任务的线程也是多个

netty工作原理示意图

img

Netty主要基于主从 Reactors多线程模型(如图)做了一定的改进

  1. BossGroup 线程维护 Selector,只关注 Accecpt
  2. 当接收到 Accept 事件,获取到对应的 SocketChannel,封装成 NIOScoketChannel 并注册到 Worker 线程(事件循环),并进行维护
  3. 当 Worker 线程监听到 Selector 中通道发生自己感兴趣的事件后,就进行处理(就由handler),注意 handler 已经加入到通道

异步执行的三种途径

1.用户程序自定义的普通任务

taskQueue自定义任务,向队列中添加异步任务

在这里插入图片描述

2.用户自定义定时任务

与上面taskQueue的区别就是加了个延时时长
在这里插入图片描述

3.非当前Reactor线程调用channel的各种方法

服务器端可以拿到所有客户端的channel,再从channel里取eventLoop就可以操作了。

在这里插入图片描述

异步模型

Future

1.Future代表异步执行的结果,可以通过它提供的方法来检测执行是否完成

2.ChannelFuture是一个接口,我们可以添加监听器,当监听的事件发生时,就会通知到监听器

当Future对象刚刚创建时,处于非完成状态,调用者可以通过返回的ChannelFuture来获取操作执行的状态,注册监听函数来执行完成后的操作。

常见的有:

isDone方法来判断当前操作是否完成;

isSuccess方法来判断已完成的当前操作是否成功;

addListener方法来注册监听器,当操作已完成(isDone方法返回完成),将会通知给指定的监听器;如果Future对象已完成,则通知指定的监听器。这样做的好处就是异步,不会阻塞,增加并发量。

在这里插入图片描述

五、开发总结

私聊实现思路:

客户端给服务端先发消息,服务端再转发

获取channel

获取channel后直接对channel操作就可以了
说白了管理客户端就是管理channel

猜你喜欢

转载自blog.csdn.net/GBS20200720/article/details/121189122