netty学习笔记整理一基础篇

 
一:.netty组件:
 服务端启动过程:通过jdk创建channel并包装为自己的channel -> init初始化channel->注册selector ->dobind()往jdk注册一个op-accept实现就可以开始接受消息了
     1. NioEventLoopGroup
    相当于serversocket接受连接bossgroup,传输消息的功能workgroup,
    其实就是线程池管理 NioEventLoop
   2. NioEventLoop
    真正接受链接,处理数据的组件,netty通过select来完成socket的接受和处理
  3.channel 
    相当于socket,通过 .channel ( NioServerSocketChannel. class )反射设置channel类型
    channel过程: jdk底层channel创建 -> channel TCP相关配置 -> 设置非阻塞模式 ->把channel注册到pipline中执行
4.handle
    进行数据业务处理的组件
5.selector
   channel 绑定eventloop 注册到jdk的selector,然后 回调注册的 ChannelInboundHandlerAdapter子类的 channelRead等 方法
 
 
二.NioEventLoop详解
 
问题引入:
  1.netty服务端启动多少个线程(默认2*cpu),什么时候启动
  2.jdk空转轮询的bug(主要是selector本来是阻塞的,但是当连接异常了,selector被唤醒了):通过时间判断selctor次数,超过512创建新的selector,把旧的key注册到新的selector
  3.netty怎么实现异步串行无锁化的:handle是线程安全的,会把线程执行封装成task放到taskQueue中顺序执行
 
1.nioeventloop创建过程(构造创建selector和定时任务队列):
默认先创建2*cpu个线程(线程前缀:nioeventloop-'i'- j):'i 第几个group组'- j(第几个线程)
每一个线程就是一个EventExecutor,也就是 nioeventloop。然后创建EventExecutorChooser ,这个东西就是为了当有链接进来的时候进行loop线程绑定,这边有做性能优化,如果线程数是2的幂等就做位运算来提高绑定效率
public EventExecutorChooser newChooser ( EventExecutor [] executors ) {
if ( isPowerOfTwo ( executors. length )) {
return new PowerOfTwoEventExecutorChooser ( executors ) ;
} else {
return new GenericEventExecutorChooser ( executors ) ;
}
}
 
2.nioeventloop启动
1.绑定端口
2.主线程使用 nioeventloop创建过程 构造函数 创建的线程task->存在 taskQueue里面-> 启动run方法
 
3.nioeventloop执行(run方法)
  for ( ;; ) 判断selector类型即检测io事件 -> select方法调用-> taskQueue中取任务进行执行
 select方法:判断selctor是否被唤醒/taskQueue是否被其他线程添加任务/是否有定时任务  满足条件执行,否则阻塞1s
 执行任务: runAllTasks:会把定时任务和普通任务合并一起执行
(通过debug发现,一次selector事件可以执行多次任务,比如client没10s发一次消息,如果debug阻塞10次,然后10次会循环输出)
然后client发送消息会继续走nioEventLoop.run() ->  runAllTasks()方法   就是有两个for循环
 
client执行任务调用的是: runAllTasks()方法,  server接受读写任务是: processSelectedKeys ()  方法
 
 
三.netty 连接处理
 1.新连接接入控制速率一次16个 
 2.新连接处理的channel:niosocketChannel
 3.niosocketChannel 客户端channel构造函数注册的是op_read事件,nioserversocketchannel 服务端channel注册的是accept事件
 
 
4.新连接NioEventLoop的分配和selector注册
添加childHandler->设置options和attrs(主要设置用户设置的一些tcp参数)->选择nioeventloop并注册selector
 
新链接处理逻辑总结:服务端检测到新连接 ->创建nioSocketChannel->绑定nioeventloop,注册selector,注册读事件
 
四. pipeline和channelHandle
 
 
inBound事件的传播:
   
   添加channelHandle:封装为channelHandleContext 放入到pipline链表中,然后触发回调通知用户已经添加
inBound是从pipline链表从头到尾执行,如果执行到最后节点,tailContext :处理未捕获的异常/未处理的消息会debug输出建议你去处理并释放消息
 
 
outBound 事件的传播:  wirte()进行回写,给client响应
outBound是从pipline链表从尾到头执行,如果中间节点不传播继续write()则结束
 
异常的传播:
如果当前handleA报错,会把错误继续向下个节点顺序传播,直到被处理,通过复写exceptionCaught处理异常
 
异常处理最佳实践:hadle链增加一个exceptionhandle。处理
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值