简单过一下Netty3.6.6.Final源码,让自己对各个流程有个稍微清晰的理解,只是文字描述,尽量描述简单,有时间再画画图
Server启动: 1.new ServerBootstrap 构造NioServerSocketChannelFactory,用来创建NioServerSocketChannel对象(newChannel方法) 1..NioServerSocketChannel:是一个parent Channel,负责接收客户端进来的连接并创建child Channel 2..NioServerSocketChannelFactory中有两类线程池: 1...BossPool<NioServerBoss> bossPool boss线程池:每个绑定的ServerSocketChannel都有自己的boss线程池,默认为一个线程,它负责接收客户端进来的连接,一旦连接成功,boss线程将Channel交给其中一个worker线程来处理 2...WorkerPool<NioWorker> workerPool work线程池:对多个Channel执行非阻塞的读写,Netty中默认为cpu核心数*2条worker线程,如果不使用worker来执行业务操 作,我喜欢将worker线程数量定在cpu核心数+1,这样比较适合执行cpu密集型任务 3..NioServerSocketChannelFactory还有一个重要对象: NioServerSocketPipelineSink sink 接收并处理下行(downstream)末端(注意下行的末端是pipeline的头结点)的ChannelEvent 2.ServerBootstrap#bind 创建一个绑定了local address的parent Channel,阻塞到绑定成功为止 1..newChannel(创建NioServerSocketChannel),传入bossPipeline、 NioServerSocketChannelFactory中的sink、bossPool(如果有多个只传入一个)、workerPool 1...ServerSocketChannel.open()一个ServerSocketChannel并设置为非阻塞模式 2...bossPipeline:默认有一个Binder,主要做以下事情: 1....处理parent Channel open,负责setOptions,以及fire ChannelState.BOUND事件 2....处理child Channel open,负责setOptions 3....对bind过程中的异常进行处理 2..在NioServerSocketChannel中fireChannelOpen,由上面的Binder处理这个parent Channel open事件 parent Channel open流程: 1...设置child pipelineFactory 2...setOptions 3...fire ChannelState.BOUND downstream事件 sink#eventSunk handleServerSocket NioServerBoss#bind 构造NioServerBoss$RegisterTask并加入taskQueue队列 3..boss线程中(NioServerBoss.RegisterTask类中)将parent Channel向selector中注册SelectionKey.OP_ACCEPT 4..bind成功返回parent Channel ================================================================================ Accepts incoming connection 1.boss[NioServerBoss]#process中调用selector.selectedKeys()拿到OP_ACCEPT的就绪parent Channel 2.boss[NioServerBoss]#process中调用parentChannel.socket.accept()创建child Channel (acceptedSocket) 3.boss[NioServerBoss]#process#registerAcceptedChannel,接收连接 1..拿到一个worker线程 2..将child Channel、parent Channel、child pipeline、sink、worker线程、boss线程组合起来构造一个NioAcceptedSocketChannel 1...设置此Channel为连接状态 2...在parent Channel的pipeline中fire child Channel state changed(child ChannelState有OPEN和CLOSED两个状态,这里是fire child ChannelState.OPEN) 1....构造ChildChannelStateEvent 2....Binder中处理child Channel open(如上文描述,就是setOptions,比如sendBufferSize、tcpNoDelay等属性) 3...在自己的child pipeline(就是我们自己定义的pipeline了)中fire child ChannelState.OPEN 3..将构造好的NioAcceptedSocketChannel向worker中注册(也就是加入到此worker的任务队列taskQueue中) 4.切换到worker线程,向worker的Selector中注册之前boss接收并创建好的child Channel(Selectionkey.OP_READ) ================================================================================ Read 1.worker调用selector.selectedKeys()拿到OP_READ的就绪child Channel 2.NioWorker.read(SelectionKey k) 1.. 分配buffer 2.. fire MessageReceived事件 3.在child pipeline调用链中执行MessageReceived ================================================================================ Write 1.构造DownstreamMessageEvent并send downstream事件,child pipeline调用链中执行(注意downstream从pipeline队尾开始) 2.在sink中将上面的DownstreamMessageEvent offer到此Channel的writeBufferQueue 3.AbstractNioWorker#write0() 1..writeBufferQueue.poll()出上面的DownstreamMessageEvent 2..分配writeBuffer 3..buf.transferTo对应child Channel 4..fire WriteComplete事件(upstream,从pipeline头结点开始) 在child pipeline调用链中执行WriteCompletion事件(如果你使用了链路空闲检测handler,比如IdleStateHandler,会在writeComplete方法中更新lastWriteTime) |
|
来自: java_laq小馆 > 《netty》