chaofx

Netty 我的深入浅出
Netty 大致流程的介绍简介TCP的长连接开发基于javaNio编程而实现,那么如果你接触过长连接开发的话 必定...
扫描右侧二维码阅读全文
10
2020/03

Netty 我的深入浅出

Netty 大致流程的介绍

简介

TCP的长连接开发基于javaNio编程而实现,那么如果你接触过长连接开发的话 必定听说过远近闻名的Netty或者mina通信框架。本文主要讲述的是java的netty框架。 netty框架在javaNio的上面进一步非常优秀的封装,解决了javaNIo的不足之处和漏洞的修复,也极大的提高了通信连接的效率。
长连接的开发 主要特点时 时效性非常的高,而非http响应式开发那样 点击反馈。所以长连接开发的范围就比较有意思了,比如说聊天,游戏,云输出。

三大核心基本组件

#### byteBuffer[java Nio] / byteBuf [netty封装]
简介: 作为最核心的 数据传输的介质, 一般的数据传输 是以流的形式传输 ,但是buffer以块的形式
buffer的 构成以包头 和 包体 来形成,包头可以放入用于处理辨别 粘包或者拆包而产生的问题,包体可以放入实际想要传送的内容。
比如说经过处理后得到包体。 根绝双方所定义好的协议规则,按照数据类型的顺序去读取实际的内容

//readInt 为读取buffer里面的int
this.titleId = readInt(buf, false);
this.writeLong(buf, lid);
this.writeString(buf, param);

区别:

  1. btyeBuffer读取数据的指针是position mark cap limit 重写数据要filp。 byteBuf的指针是readIndex 和writeIdnex 有效的避免了bytebuffer的filp 操作
  2. bytebuf在write数据的时候会自动扩容,btyeBuffer需要开发者自己去拷贝到一个更大的buffer中 因为它的btye[] 是final的
  3. byteBuf根绝传输的数据会来guess猜测每次接受数据的大小。

回收方式:根绝引用回收法 记录回收buffer

堆外缓存和堆内缓存
堆外缓存:

*  优势:可以是jvm直接调用获取array 字节数组,操作更加灵活,垃圾回收效率高
*  弱势:io操作效率低、需要拷贝到直接缓冲才可传输

堆内缓存:

* 优势:socket io操作效率非常好
* 弱势:是由操作系统管理的内存,分配和释放都比较复杂,回收效率不高

堆外内存概念 奠定了零拷贝的实现

channel

简介:作为一个传输的通道, 一个channel的生命周期只会绑定一个evenetloop。
channel里面有 channelpipline 包含 channelhandlerContext -> [channelhander <具体的业务处理>]
channelOption是channel的基本配置

writeAndflush 作用于数据缓冲读写

selecotr

简介:事件分离器 ,轮询等待时间的发生,每一个eventloop都有一个事件分离器selector,通过select.in()方法监听事件发生。可以在soketChannel注册 感兴趣的事件比如 op_connect 或者 op_accept.

netty运行的工作模型

netty工作大致流程
直接看图说话。。。。

NioEventGroup

NioEventGroup 里面放了若干个EventLoop ,Eventloop实质上是netty对于线程池的封装, 它用于注册和和调度任务队列。
一个channel 整个生命周期 只与一个 eventloop绑定.
图中的bossgroup这块模块只管理 channel 的连接, workerGroup 用于业务处理的管理 ,所以看到业务处理的线程池会比较多一点。
Acceptor 中间媒介 把channel注册到worketGroup里面的NioEventLoop上面。
当有读操作事件被监听到的时候,根绝eventLoop的调度 在进入自己业务逻辑的时候 会经历一个channelpiple 里面会有若个channelInboundHander要被执行,相当于shiro那样过滤器一样操作。 写操作也是如此。。。


再谈一下zero copy

说这个之前 我们先来讲一下 什么是用户空间 什么是 内核空间。
用户空间:是非特权区域,在该区域执行的代码不能直接访问硬件设备,常规进程就在本区域执行,JVM就是常规进程,所以JVM进程驻守在用户空间 这相当于 javaNative内存堆
内核空间:是操作系统所在区域,有特别的权利:能与设备控制器通讯,控制着用户区域进程的运行状态等等,最重要的是,所有I/O都直接或间接的通过内核空间 从磁盘拷入 必须要经过内核空间缓冲区,这是操作系统上的拷贝
1.通常的io数据拷贝流程

磁盘-> 内核空间缓存区-> 用户内存区, 用户内存-> 内核缓存->磁盘 这样涉及到四次拷贝

2.操作系统上的零拷贝

数据在内核空间缓冲区socket通道里面,可以通过映射文件改变 用户内存的数据【native堆内存】,省去用户空间的拷贝。

3.真正的零拷贝

内核空间缓存拷贝到 scoket通道里面是一个内存地址,通过协议引擎发送 就读取上面地址 找到内核缓冲区的数据发送

Netty的文件传输采用了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题。

零拷贝就是不停的减少拷贝次数,意义在于内核空间和用户空间的博弈 ,netty里面以btyebuf最为堆外直接缓冲实现zero cop y 重点也要把握堆内存的数据管理。

版权属于:本文为原创文章,版权归本博所有,转载请注明出处!。

如果文章 语句 文字 描述等有错误 只能请在座的各位多多包涵 博主说话没有切格瓦拉好听。

感谢您本次的阅读

Last modification:April 27th, 2020 at 07:26 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

隐藏