Netty基础入门

1.netty的高性能表现在哪些方面?对平常的项目开发的启发?
 Reactor线程模型
2.netty中有哪些重要的组件,他们之间的联系?
3.netty的内存池,对象池是怎么设计的?
4.针对netty你有哪些印象深刻的系统调优案例?

netty对Java NIO进行了高级封装(拆包、粘包,数据编解码,TCP断线重连),简化了网络应用的开发过程

为什么要学习netty:


1.I/O模型,线程模型,事件处理机制
2.易用的API接口
3.数据协议,序列化的支持

 

I/O请求的两阶段:
1.I/O调用阶段:用户进程向内核发起系统调用
2.I/O执行阶段:内核等待I/O请求处理完成返回
   2.1:I/O设备获取数据到内核缓冲区
   2.2:数据从内核缓冲区拷贝到用户态缓冲区

Linux的5种主要I/O模型:
1.同步阻塞I/O(BIO)

 
2.同步非阻塞I/O(NIO)


3.I/O多路复用

一个线程实现处理多个I/O句柄的操作
select  poll  epoll 都是I/O多路复用的具体实现

 

4.信号驱动I/O(半异步的I/O模型,内核通知何时可以开始I/O操作)


5.异步I/O
  从内核缓冲拷贝到用户态缓冲区也是由系统异步完成,由内核通知何时I/O操作已经完成

 

netty基于非阻塞I/O实现自己的I/O模型
底层依赖的是JDK NIO框架的多路复用器Selector
一个Selector可以同时轮训多个Channel

当有数据处于就绪状态,需要一个事件分发器(Event Dispather)将事件分发给对应的读写事件处理器(Event Handler)
事件分发器有两种设计模式:
Reactor(采用同步IO)和Proactor(采用异步IO)


主流事件驱动模型还是依照select或epoll

Netty的整体架构脉络

 逻辑架构:


1.网络通信层
 职责是进行网络I/O操作,支持多种网络协议和I/O模型的连接操作
 BootStrap --主要负责整个Netty程序的启动,创建,初始化Channel等,远端服务器连接,只绑定一个EventLoopGroup(Boss)
 ServerBootStrap  --服务器端启动,绑定本地端口,绑定两个EventLoopGroup(Worker)
 Channel --是网络通信的载体,提供了与底层Socket交互的能力,提供了基本的API用于网络I/O操作,register,bind,connect,read,write,flush等

 

2.事件调度层
职责是通过Reactor线程模型对各类事件进行聚合处理
通过Selector主循环线程集成多种事件(I/O事件,信号事件,定时事件)

EventLoopGroup--本质是个线程池并分配线程执行处理请求,是Netty Reactor线程模型的具体实现方式
EventLoop--负责向注册的Channel发起I/O读写操作,处理网络连接生命周期的所有I/O事件(accept,connect,read,write)
每个EventLoop是单线程的,通过selector进行事件循环

EventLoopGroup 根据不同的参数配置,实现Reactor的3种线程模型:

 

3.服务编排层
职责是组装各类服务,用以实现网络事件的动态编排和有序传播
ChannelPipeline--组装编排各种ChannelHandler
ChannelHandler--实际数据的编解码以及加工处理操作
ChannelHandlerContext 

每一个新的Channel会对应绑定一个新的ChannelPipeline
一个ChannelPipeline关联一个EventLoop
一个EventLoop仅会绑定一个线程

网络通信层--BootStrap 


服务端启动过程:
1.配置线程池:
单线程模式:
EventLoopGroup group = new NioEventLoopGroup(1);
ServerBootstrap b = new ServerBootstrap();
b.group(group)

多线程模式:
EventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(group)

主从多线程模式:
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)

2.Channel初始化
2.1.设置 Channel 类型
b.channel(NioServerSocketChannel.class);

2.2.注册 ChannelHandler
b.childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) {
        ch.pipeline()
                .addLast("codec", new HttpServerCodec())
                .addLast("compressor", new HttpContentCompressor())
                .addLast("aggregator", new HttpObjectAggregator(65536)) 
                .addLast("handler", new HttpServerHandler());
    }
})

2.3.设置 Channel 参数
b.option(ChannelOption.SO_KEEPALIVE, true);

3.端口绑定
ChannelFuture f = b.bind().sync();

事件调度层--EventLoop


EventLoop是Netty Reactor线程模型的核心处理引擎,是一种事件等待和处理的程序模型,可以解决多线程资源消耗高的问题
每个EventLoop线程都维护一个Selector选择器和任务队列taskQueue
主要负责处理I/O事件,普通任务,定时任务

主流网络框架都采用I/O多路复用的方案, Reactor模式作为其中的读写事件分发器,负责将读写事件分发给对应的读写事件处理者

EventLoop运行模式:

 源码:
1.select(wakeUp.getAndSet(false)); //轮训I/O事件
2.processSelectedKeys(); //处理I/O事件


3.runAllTasks(); //处理任务
 |-1.合并定时任务到普通任务队列
     fetchFromScheduledTaskQueue();
 |-2.从普通任务队列中取出任务
     pollTask();
 |-3.计算任务处理的超时时间
     dealline = ScheduledFutureTask.nanoTime()+timeoutNanos;
 |-4.安全执行任务
     safeExecute(task);
 |-5.每执行64个任务检查下是否超时,
 |-6.收尾工作
     afterRunningTasks();

NioEventLoop 无锁串行化设计:
优点:
使系统吞吐量达到最大化
降低了用户开发业务逻辑的难度

缺点:
不能执行时间过长的I/O操作,一旦一个I/O事件发生阻塞,后续所有I/O事件都无法执行

JDK中epoll的实现是存在漏洞的
即使selector轮训的事件列表为空,NIO线程一样会被唤醒,导致CPU100%占用。
Netty 的事件轮训中,

1.每次selector之前记录currentTimeNanos,

2.如果事件轮训时间>=timeoutMills则正常的

3.通过selector_auto_rebuild_threshold阈值,通过selectCnt>该值时触发重建selector对象 并break

处理任务:


总结:
MainReactor线程:处理客户端请求接入
SubReactor线程:数据读取,I/O事件的分发与执行
任务处理线程:执行普通任务或者定时任务,如空闲连接检测,心跳上报

服务编排层--ChannelPipline与ChannelHandler

channelpipline负责调度各种类型的ChannelHandler,实际数据的加工处理由ChannelHandler完成

ChannelPipline是双向链表结构

ChannelInboundHandler和ChannelOutboundHandler

每个channelHandler由一个ChannelHandlerContext封装

Inbound和Outbound传播方向相反

(head-tail)  (tail-head)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值