Netty

时间:2020-07-16 16:13:52   收藏:0   阅读:48

1. 学习目的

  1. BIO、NIO和AIO的区别?
  2. NIO的组成?
  3. Netty的特点?
  4. Netty的线程模型?
  5. TCP 粘包/拆包的原因及解决方法?
  6. 了解哪几种序列化协议?
  7. 如何选择序列化协议?
  8. Netty的零拷贝实现?
  9. Netty的高性能表现在哪些方面?
  10. NIOEventLoopGroup源码?

2.学习Netty

  1. 为什么学习Netty
    分布式的时代 分布式框架中要用到
    Spring5 去servlet化,底层使用netty
    SpringBoot 内部实现web容器
    Zookeeper 底层通信
    Dubbo 分布式服务框架,多协议支持(RPC) Netty
    为成为架构师筑基
  2. Netty能帮助我们解决什么问题?
    框架:简化开发一系列解决方案的集合
    封装IO操作的框架
    复杂的业务场景中,没有说用一个单独的IO APi,经常遇到的问题:手写线程(Thread),多线程处理、性能问题、单双工,影响业务的开发。
    IO + 多线程来解决问题
    类似的框架:Mina Netty的前身(不是一个人开发的)
  3. 为什么要封装IO操作
    阻塞和非阻塞:
    自己回答:处理端在处理数据的时候,如果被处理对象的数据没有准备好,线程会阻塞在当前线程,譬如socket.accept()方法 ,在等待网络连接的时候,如果没有请求连接,线程会处于阻塞状态,如果是非阻塞模型,当前线程可以去处理其他事物

Input Output
是相对于内存而言
磁盘只是input output的一端,除了磁盘还有网络

IO模型

阻塞非阻塞:参照IO操作 读数据或取数据时候的一种处理机制

BIO阻塞:

NIO:
通道 Buffer 轮询

同步与异步

在处理数据的时候,在同一时间点能同时做多个处理:异步
在同一时间只能做一个处理:同步

NIO的操作过于繁琐,于是有了Netty,对NIO进行了封装。

IO(BIO)Block IO 同步阻塞IO
NIO Non-Block IO 同步非阻塞IO (可以使用线程池的方式,实现异步)
AIO Async IO 异步非阻塞IO (事件驱动,回调实现异步)

3. NIO

3.1 NIO的核心组件(三件套)

  1. Buffer、Selector、Channel、

3.1.1 Buffer

  1. 缓冲区属性
    容量:capacity:表示该缓冲区可以保存多少数据。
    极限:limit:表示缓冲区的当前终点,不能对缓冲区中超过极限的数据进行读写操作。极限可以修改,有利于缓冲区的重用。
    位置:position:表示缓冲区中下一个读写单元的位置,每次读写缓冲区的数据时,都会改变位置值,为下一次读写数据做准备。
    属性关系为 capacity>=limit>=position>=0
  2. 改变缓冲区3个属性的方法
    clear():把极限限制为容量值,再把位置设为0.
    flip():把极限值设为位置值,再把位置设为0.
    rewind():不改变极限,把位置设为0.
  3. ByteBuffer类没有提供公开的构造方法,但是提供了两个获得ByteBuffer实例的静态工厂方法。
    allocate(int capacity):返回一个ByteBuffer对象
    directAllocate(int capacity):返回一个ByteBuffer对象,称为直接缓冲区
  4. 所有的缓冲区都提供了读写缓冲区的方法
    get():相对读。从缓冲区的当前位置读取一个单元的数据,读完后把位置值加1。
    get(index):决对读。从参数index指定的位置读取一个单元的数据。
    put():相对写。向缓冲区的当前位置写入一个单元的数据,写完后把位置值加1.
    put(int index):绝对写。向参数index指定的位置写入一个单元的数据。

3.1.2 Selector

3.1.3 Channel

是多路复用的基础
解决的问题:

  1. 请求过多,导致连接线程过多
  2. 处理数据较大,导致线程长时间占用 也会导致阻塞
    selector模型,IO调用不会被阻塞,

3.2何为多路复用

3.3Netty支持的功能与特性

Netty

Netty封装了NIO,Reactor模型,声明BOSSS线程,worker线程,可以修改BOSS线程和worker线程的数量

  1. 编码过程
    //Netty服务 //NIO //BIO
    ServerBootstrap ServerSocketChannel ServerSocket

主线程处理类,这样的写法,底层使用反射

子线程处理类 ,Handler

无锁化串行编程

编码器

解码器

业务处理逻辑

针对主线程的最大配置数

针对子线程的配置,保持长连接

//SocketChannel的封装
ChannelHandlerContext

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。

协议编解码
2. Netty支持的协议
官网图

Netty的高性能

比传统IO性能提升了8倍多。

  1. 阻塞IO不具备弹性伸缩能力(一个请求,一个应答),高并发导致宕机
  2. Java序列化编码、解码的性能问题,直接是字节流的读写
  3. 传统IO线程模型过多占用CPU资源
  1. 接收和发送ByteBuffer使用堆外内存直接内存进行socket读写。
  2. 提供了组合Buffer对象,可以聚合多个ByteBuffer对象。
  3. transfreTo()直接将文件缓冲区的数据发送到目标Channel,避免循环导致内存拷贝的问题。
  1. Pooled与unPooled(池化与非池化)
  2. UnSage和非UnSafe(底层读写与应用程序读写)
  3. Heap与Direct(堆内存与堆外内存)
    netty有pooled buffer 和 unpooled buffer
    pooled 先初始化一定大小的空间 ,读写效率 ,内存分配 堆外内存读写高,但是内存管理比较麻烦。
  1. Reactor单线程模型
    netty的接收连接,分发调度、读写都由一个线程完成。
  2. Reactor多线程模型
    反应接待线程、反应线程池(处理读写,编解码)
  3. 主从Reactor多线程模型
    接收线程 主线程池(调度不同模块业务的资源) 派发不同的业务逻辑线程
    从线程

MessageToMessageEncoder extends ChannelOutboundHandlerAdapter 是一个OutBound,OutBound说明数据需要一个回调处理了。

  1. volatile的大量、正确使用
  2. CAS和原子类的广泛使用
  3. 线程安全容器的使用
  4. 通过读写锁提升并发性能
  1. 序列化后的码流大小(影响网络带宽的占用)
  2. 序列化&反序列化的性能(CPU资源占用)
  3. 是否支持跨语言(异构系统的对接和开发语言切换)

Netty核心之服务端Channel源码分析

服务端Channel的创建
bind()[用户代码入口]
initAndRegister()[初始化并注册]
newChannel()[创建服务端channel]
init()[初始化服务端Channel]

原文:https://www.cnblogs.com/nangonghui/p/13290323.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!