美文网首页
netty-总结

netty-总结

作者: coderljx | 来源:发表于2019-01-13 17:17 被阅读0次

    参考闪电侠https://www.jianshu.com/u/4fdc8c2315e8系列文章

    服务端启动总结:
    1.设置启动类参数,最重要的就是设置channel
    2.创建server对应的channel,创建各大组件,包括ChannelConfig,ChannelId,ChannelPipeline,ChannelHandler,Unsafe等
    3.初始化server对应的channel,设置一些attr,option,以及设置子channel的attr,option,给server的channel添加新channel接入器,并出发addHandler,register等事件
    4.调用到jdk底层做端口绑定,并触发active事件,active触发的时候,真正做服务端口绑定

    新连接接入:
    1.boos reactor线程轮询到有新的连接进入
    2.通过封装jdk底层的channel创建 NioSocketChannel以及一系列的netty核心组件
    3.将该条连接通过chooser,选择一条worker reactor线程绑定上去
    4.注册读事件,开始新连接的读写

    reactor线程干的事儿:
    https://img.haomeiwen.com/i1357217/67ed6d1e8070426f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp
    1.轮询IO事件
    2.处理轮询到的事件
    3.执行任务队列中的任务

    轮询IO事件:
    不断地轮询是否有IO事件发生,并且在轮询的过程中不断检查是否有定时任务和普通任务,保证了netty的任务队列中的任务得到有效执行,轮询过程顺带用一个计数器避开了了jdk空轮询的bug,过程清晰明了

    处理轮询到的事件:
    netty的reactor线程第二步做的事情为处理IO事件,netty使用数组替换掉jdk原生的HashSet来保证IO事件的高效处理,每个SelectionKey上绑定了netty类AbstractChannel对象作为attachment,在处理每个SelectionKey的时候,就可以找到AbstractChannel,然后通过pipeline的方式将处理串行到ChannelHandler,回调到用户方法。

    执行任务队列中的任务:
    当前reactor线程调用当前eventLoop执行任务,直接执行,否则,添加到任务队列稍后执行
    netty内部的任务分为普通任务和定时任务,分别落地到MpscQueue和PriorityQueue
    netty每次执行任务循环之前,会将已经到期的定时任务从PriorityQueue转移到MpscQueue
    netty每隔64个任务检查一下是否该退出任务循环

    pipline 总结:
    1.以新连接创建为例,新连接创建的过程中创建channel,而在创建channel的过程中创建了该channel对应的pipeline,创建完pipeline之后,自动给该pipeline添加了两个节点,即ChannelHandlerContext,ChannelHandlerContext中有用pipeline和channel所有的上下文信息。
    2.pipeline是双向个链表结构,添加和删除节点均只需要调整链表结构
    3.pipeline中的每个节点包着具体的处理器ChannelHandler,节点根据ChannelHandler的类型是ChannelInboundHandler还是ChannelOutboundHandler来判断该节点属于in还是out或者两者都是
    4.一个Channel对应一个Unsafe,Unsafe处理底层操作,NioServerSocketChannel对应 NioMessageUnsafe, NioSocketChannel对应NioByteUnsafe
    5.inBound事件从head节点传播到tail节点,outBound事件从tail节点传播到head节点
    6.异常传播只会往后传播,而且不分inbound还是outbound节点,不像outBound事件一样会往前传播

    writeAndFlush:
    1.pipeline中的编码器原理是创建一个ByteBuf,将java对象转换为ByteBuf,然后再把ByteBuf继续向前传递
    2.调用write方法并没有将数据写到Socket缓冲区中,而是写到了一个单向链表的数据结构中,flush才是真正的写出
    3.writeAndFlush等价于先将数据写到netty的缓冲区,再将netty缓冲区中的数据写到Socket缓冲区中,写的过程与并发编程类似,用自旋锁保证写成功
    4.netty中的缓冲区中的ByteBuf为DirectByteBuf

    相关文章

      网友评论

          本文标题:netty-总结

          本文链接:https://www.haomeiwen.com/subject/hhlldqtx.html