近期在研究Netty源码,决定写一篇Netty的博客,既可以当做学习笔记,又可以同大家分享我的学习历程,如果有错误的地方,还望各位大佬指出,不胜感激。
netty运行原理如上图所示:
1.客户端首先会向指定地址的指定端口发送一个连接请求,服务器会有个NioServerSocketChannel监听此端口,当有连接请求发送过来后,会将此请求发送给EventLoopGroup(boss),然后EventLoopGroup会将此请求分配一个EventLoop,并和该EventLoop的Selector绑定。**
EventLoopGroup是事件循环组,里面有个多个EventLoop,每个EventLoop又有一个自己的线程,因此
EventLoopGroup也是一个线程组,默认的线程数是CPU*2。
EventLoopGroup分为两种,一个是Boss,一个是worker。Boss事件循环组是用来处理监听事件的,worker
事件循环组是用来处理读写事件的
2.当客户端和boss的EventLoop绑定完成之后,会生成一个SocketChannel并将其注册到worker的EventLoopGroup里,worker的EventLoopGroup会将他和自己组内的一个EventLoop绑定,之后客户端的channel和服务端的channel之间就可以进行网络通信了,EventLoop(worker)的selector会持续监听该channel里的读写时间并处理。
一个EventLoop可以同时监听多个channel的读写事件,也就是说一个EventLoop可以绑定多个Channel,但
是一个Channel只能绑定一个EventLoop
3.当SocketChannel创建时,会调用一个ChannelInitializer的初始化方法,这个方法会组装一个ChannelPipeLine,并且将你自定义的入站Handler、出站Handler组装到该pipeline,用来处理后续的读写数据
ChannelPipeLine是一个责任链模式的数据处理链,里面包含了入站、出站的处理器,是个双向链表的结构,虽
然都在一个链表里,但是入站处理器和出站处理器互不干扰,每次都只会执行链条中的同一类处理器。
ChannelPipeLine初始化的时候,哪怕你没有向里面组装自定义的处理器,他也会初始化两个处理器用来当做链表的tail和head节
点。ChannelPipeLine链条中传递的参数是ChannelHandlerContext,我们可以从该上下文中获取当前的
pipeline。
4.当读写请求入站的时候,ChannelPipeLine会执行ChannelInBoundHandler类型的处理器,然后将处理之后的数据传给EventLoop的处理线程。当EventLoop线程处理完结果之后,会执行ChannelOutBoundHandler类型的处理器,并且从尾往前执行,走完出站处理器链条之后,会将响应结构写回到Channel,之后客户端的Channel会收到响应数据。
Netty里的数据都是以ByteBuf的数据形式进行传输的,和NIO的ByteBuff类似但不相同。