一 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. Python基础之第三方库gevent安装

    安装gevent库: 想要安装gevent库,我们需要确定pip版本: 使用 pip3 list: 我们可以发现pip版本为19.3.1,如果你们的pip版本不是最新版可以使用命令python -m ...

  2. JavaScript的函数申明、函数表达式、箭头函数

    JavaScript中的函数可以通过几种方式创建,如下. // 函数声明 function getName() { return 'Michael' } // 函数表达式 const getName ...

  3. Oracle触发器用法--基础教学

    1.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好了.这里面需 ...

  4. HDU 6405 Make ZYB Happy(广义SAM)

    It's known to all that ZYB is godlike, so obviously he has a large number of titles, such as jskingj ...

  5. CSU OJ2151 集训难度

    小L正在组织acm暑假集训,但众所周知,暑假集训的萌新中有OI神犇,也有暑假才开始学算法的萌新,如果统一集训的难度,无法很好地让萌新们得到训练,所以小L想了一个办法,根据每次测试的情况,改变萌新们的集 ...

  6. MySQL 04

    目录 python操作mysql mysql sql注入问题 问题描述 解决办法 增/删/改 查询 索引 基本概念 索引的原理 mysql索引种类 普通索引 唯一索引 联合索引 创建索引 正确使用索引 ...

  7. 【Hybrid】288- Hybrid App 应用开发中 9 个必备知识点复习

    前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...

  8. Mybatis需要注意的细节

    mybatis第二篇 1.${}和#{}的区别 1.#在传参的时候,会自动拼接单引号:$不能拼接单引号; 2.$传参时,一般不支持jdbcType指定类型的写法;#则可以;如: ​ #{name,jd ...

  9. Spring AOP应用场景你还不知道?这篇一定要看!

    回顾一下Spring AOP的知识 为什么会有面向切面编程(AOP)? 我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日 ...

  10. 11个点让你的Spring Boot启动更快

    前言 使用的是 OpenJDK 11. java --version openjdk 11.0.1 2018-10-16 OpenJDK Runtime Environment 18.9 (build ...