一 Netty服务端NioEventLoop的启动

Netty服务端创建、初始化完成后,再向Selector上注册时,会将服务端Channel与NioEventLoop绑定,绑定之后,一方面会将服务端Channel的注册工作当做Runnable任务提交到NioEventLoop的taskQueue,另一方面,会开始NioEventLoop的启动工作。从服务端Channel注册Selector代码的入口一直跟踪,到如下代码时,开始进行以上所说的操作。
以上代码中eventLoop.inEventLoop()方法会判断当前线程是不是在NioEventLoop中运行,初次运行在此,NioEventLoop中的thread变量还没有被赋值,所以返回false,执行eventLoop.execute方法,如下代码所示,其中addTask方法将服务端Channel的注册工作当做Runnable任务加入到taskQueue队列。同样,inEventLoop变量为false,后面便开始执行启动NioEventLoop的代码startThread方法。
 
 
代码运行在这里后,NioEventLoop就启动完毕,开始执行其run方法,在它的run方法中,NioEventLoop会做如下三件事:
①轮询Channel中准备就绪的IO事件
②处理准备就绪的IO事件
③处理在任务队列中的非IO任务,包括定时任务
下面主要分析一下服务端对新连接接入的处理。

二 Netty服务端接入新连接处理

从上图所示的processSelectedKeys()方法进入往后跟一下,会到处理每一个key的processSelectedKey()方法,进入该方法后首先会判断key的有效性,然后便根据key所关联的Channel已经准备好的事件进行分类处理,下图红框中的代码就是服务端处理新连接接入的代码,unsafe.read()方法会进入NioMessageUnsafe类的read方法,其中NioMessageUnsafe类是AbstractNioMessageChannel类的内部类。
 
由以上代码可知,服务端处理新连接接入时先accept新连接,doReadMessages中只做了很简单的操作,如下代码所示,首先accept返回一个Java Nio底层SocketChannel,然后封装为Netty的NioSocketChannel放入List中,NioSocketChannel在创建过程中,也和创建服务端Channel类似会为客户端Channel创建一系列Netty核心组件,比如Pipeline、unsafe等。
接下来就是就是真正的处理新接入的服务端Channel了,有一点先要明确,此时服务端Channel的pipeline为:
head → ServerBootstrapAcceptor → tail,当执行pipeline.fireChannelRead(NioSocketChannel)方法时,事件沿着pipeline上的handler进行传播,到ServerBootstrapAcceptor 的channelRead方法中开始处理新接入的客户端Channel。在分析对客户端Channel的处理之前,先看看在用户代码中配置ServerBootstrap的一个简单示例:
 
ServerBootstrapAcceptor 的channelRead方法:
在channelRead方法中,首先将上游handler传来的msg强转为Channel,然后配置客户端Channel的pipeline,在pipeline中添加的childHandler就是在用户代码中配置ServerBootstrap时childerHander方法中传入的ChannelInitializer这个handler,在后面会由ChannelInitializer的initChannel方法构造出真正处理数据的客户端Channel的pipeline。此时,客户端Channel的pipeline为:head → ChannelInitializer → tail。设置完客户端Channel的option与attr后,将会进行客户端Channel的注册工作,这一流程和注册服务端Channel基本一致,区别是服务端Channel注册过程中是与boosGroup中的线程绑定,而客户端Channel是与workGroup中的线程绑定。childGroup.register方法的childGroup就是用户配置ServerBootstrap是传入的workGroup。
childGroup.register方法跟进去后如上所示,next()会返回workGroup中的一个线程,后面的注册过程就和服务端Channel的注册一模一样了。
 
至此,Netty服务端接收了一个客户端连接,还为客户端Channel绑定了一个workGroup中的线程,并且完成了客户端Channel的注册及启动客户端Channel所绑定NioEventLoop。

Netty服务端NioEventLoop启动及新连接接入处理的更多相关文章

  1. Netty服务端的启动源码分析

    ServerBootstrap的构造: public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Serve ...

  2. Netty 学习(八):新连接接入源码说明

    Netty 学习(八):新连接接入源码说明 作者: Grey 原文地址: 博客园:Netty 学习(八):新连接接入源码说明 CSDN:Netty 学习(八):新连接接入源码说明 新连接的接入分为3个 ...

  3. netty服务端客户端启动流程分析

    服务端启动流程 我们回顾前面讲解的netty启动流程,服务端这边有两个EventLoopGroup,一个专门用来处理连接,一个用来处理后续的io事件 服务端启动还是跟nio一样,绑定端口进行监听,我们 ...

  4. Netty是如何处理新连接接入事件的?

    更多技术分享可关注我 前言 前面的分析从Netty服务端启动过程入手,一路走到了Netty的心脏——NioEventLoop,又总结了Netty的异步API和设计原理,现在回到Netty服务端本身,看 ...

  5. Netty 服务端创建

    参考:http://blog.csdn.net/suifeng3051/article/details/28861883?utm_source=tuicool&utm_medium=refer ...

  6. ZooKeeper单机服务端的启动源码阅读

    程序的入口QuorumPeerMain public static void main(String[] args) { // QuorumPeerMain main = new QuorumPeer ...

  7. Netty 服务端启动过程

    在 Netty 中创建 1 个 NioServerSocketChannel 在指定的端口监听客户端连接,这个过程主要有以下  个步骤: 创建 NioServerSocketChannel 初始化并注 ...

  8. netty服务端启动--ServerBootstrap源码解析

    netty服务端启动--ServerBootstrap源码解析 前面的第一篇文章中,我以spark中的netty客户端的创建为切入点,分析了netty的客户端引导类Bootstrap的参数设置以及启动 ...

  9. Netty之旅三:Netty服务端启动源码分析,一梭子带走!

    Netty服务端启动流程源码分析 前记 哈喽,自从上篇<Netty之旅二:口口相传的高性能Netty到底是什么?>后,迟迟两周才开启今天的Netty源码系列.源码分析的第一篇文章,下一篇我 ...

随机推荐

  1. 循环神经网络(RNN)的改进——长短期记忆LSTM

     一:vanilla RNN 使用机器学习技术处理输入为基于时间的序列或者可以转化为基于时间的序列的问题时,我们可以对每个时间步采用递归公式,如下,We can process a sequence ...

  2. oc工程中oc、swift混编代码打包成静态framework踩坑笔记

    参考资料: https://www.jianshu.com/p/734341f7c242 https://www.jianshu.com/p/55038871e7de   两天时间探索,期间不知道遇到 ...

  3. SpringBoot整合freemarker模板

    一.目录展示 二.导入依赖 三.application.properties配置文件 四.在src/main/resource/templates文件夹中创建HelloFreeMarker.ftl文件 ...

  4. jquery.validate的一个bug

    在用jquery.validate.js做输入验证中,用到了对某个字段重复性的判断,就是在某字段的验证中使用remote进行输入时用ajax不断向后台发送请求,但是奇怪的是,在你在data:{}中用n ...

  5. spring-MVC_笔记

    需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转. ①导入SpringMVC相关坐标②配置SpringMVC核心控制器DispathcerServlet ③创建Controller类和视 ...

  6. ajax异步请求的三种常见方式

    首先先介绍下ajax,ajax(ASynchronous JavaScript And XML)为异步的javascript和xml.所谓的异步和同步是指: 同步:客户端必须等待服务器的响应,在等待期 ...

  7. Java并发编程学习随笔 (一) 使用run() 和 start()的差别

    java多线程run()和start()的区别 当你启动线程,使用start(),系统会把run()方法当成线程执行体来处理,这是正常的,也是正确的情况.但是,当你启动线程时,调用run()方法,系统 ...

  8. [ch05-01] 正规方程法解决多变量线性回归问题

    系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 5.1 正规方程解法 英文名是 Normal Equat ...

  9. 在mac上如何用safari浏览器调试ios手机的移动端页面

    第一步 打开iphone手机的开发者模式,流程是:[设置]->[Safari]->[高级]->开启[Web检查器] 第二步 打开Mac上Safari的开发者模式,流程是[Safari ...

  10. [TimLinux] JavaScript 元素动态显示

    1. css的opacity属性 这个属性用于:设置元素的不透明级别,取值范围:从 0.0 (完全透明)到 1.0(完全不透明),元素所在的文本流还在.这个属性的动态变化可以用来设置元素的淡入淡出效果 ...