create NioEventLoopGroup Instance

一、NioServerSocketChannel init

note:Initializing ChannelConfig creates a WriteBufferWaterMark instance,Default low 32k,high 64k
  作用: 防止ChannelOutboundBuffer 太大最终导致内存溢出,达到 High water值,
  会传播ChannelHandler 的 channelWritabilityChanged method,但是依旧能 write to buffer
  需要依据ChannelOutboundBuffer.isWritable 方法判断是否继续 write 处理.
  
  方案:after write to buffer,调用 ChannelOutboundBuffer,isWritable 方法是否可写,不可写时候,
  调用Channel config AutoRead 置为false,停止从Socket接收缓冲区读取到应用缓冲区
  (利用Tcp协议栈的滑动窗口做流控),监听ChannelHandler.channelWritabilityChanged 方法处理是否
  恢复AutoRead:true

二、NioServerSocketChannel performs

register0 method code int the AbstractChannel class:

private void register0(ChannelPromise promise) {
try {
// check
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
doRegister();//Selector register ServerSocketChannel
neverRegistered = false;
registered = true; // 传播 ChannelHandler 的 handlerAdded 方法(先执行 initChannel 方法)
// 之前在ServerBootstrap 类中定义的init 方法里将会触发ChannelInitializer 的执行
// performs complete, remove current ChannelHandler
pipeline.invokeHandlerAddedIfNeeded(); safeSetSuccess(promise);//如果启用listener,callBacks Results //传播 channelHandler 的 channelRegistered 方法
pipeline.fireChannelRegistered(); // 是否传播 ChannelHandler 的 channelActive 方法
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {//默认AutoRead:true(是否从Socket接收缓冲区读取数据)
beginRead();
}
}
} catch (Throwable t) {
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}

note:sun Jdk的Selector选择是依据 OS 来挑选 select、poll、epoll.


三、ChannelPipeline, Channel, ChannelHandler 和 ChannelHandlerContext 的关系

.Channel 绑定到 ChannelPipeline
.ChannelPipeline 绑定到 包含 ChannelHandler 的 Channel
.ChannelHandler
.当添加 ChannelHandler 到 ChannelPipeline 时,ChannelHandlerContext 被创建

四、Client Connection to Server



note:传播之前添加的ServerBootstrapAcceptor(ChannelHandler) 的 channelRead 方法

note:ParentDefaultChannelPipeline -> NioServerSocketChannel
SubDefaultChannelPipeline -> NioSocketChannel(a TcpConnection map a NioSocketChannel)
流程和NioServerSocketChannel一致,对Multi NioScoketChannel采用分治思想,多线程去承担(IO Read/Write),
利用multi core cpu.

Core Code in the ServerBootstrap.ServerBootstrapAcceptor Class: 

public void channelRead(ChannelHandlerContext ctx, Object msg) {
final Channel child = (Channel) msg;//Converted to NioSockerChannel child.pipeline().addLast(childHandler);//Add Application setting childHandler //添加Application 配置的相关属性和选项
setChannelOptions(child, childOptions, logger); for (Entry<AttributeKey<?>, Object> e: childAttrs) {
child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
} //切换NioSocketChannel 到其他线程的Scheduling和Register
try {
childGroup.register(child).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {//操作结果失败
forceClose(child, future.cause());
}
}
});
} catch (Throwable t) {
forceClose(child, t);
}
}

五、Client transmits data to the Server

Core Code in the AbstractNioByteChannel.NioByteUnsafe Class:

public final void read() {
final ChannelConfig config = config();//获取NioSocketChannel 配置
//检查是否可读
if (shouldBreakReadReady(config)) {
clearReadPending();
return;
}
//接收缓存区分配器
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
allocHandle.reset(config);//重置 ByteBuf byteBuf = null;
boolean close = false;
try {
  //NioSocketChannel配置(AutoRead)是否可读,最大读取次数范围内是否读取数据流完毕
do {
byteBuf = allocHandle.allocate(allocator);//分配byteBuf
allocHandle.lastBytesRead(doReadBytes(byteBuf));//读取数据流
if (allocHandle.lastBytesRead() <= ) {//是否读取完毕
byteBuf.release();//释放资源
byteBuf = null;
close = allocHandle.lastBytesRead() < ;
if (close) {
readPending = false;
}
break;
} allocHandle.incMessagesRead();//递增一次读取次数
readPending = false;
pipeline.fireChannelRead(byteBuf);//Callbacks channelRead ChannelHandler
byteBuf = null;
} while (allocHandle.continueReading()); allocHandle.readComplete();
pipeline.fireChannelReadComplete();//Callbacks channelReadComplete ChannelHandler if (close) {
closeOnRead(pipeline);
}
}
...
}
}
 
Flow:
I/O Request
Channel
|
+---------------------------------------------------+---------------+
| ChannelPipeline | |
| \|/ |
| +---------------------+ +-----------+----------+ |
| | Inbound Handler N | | Outbound Handler | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler N- | | Outbound Handler | |
| +----------+----------+ +-----------+----------+ |
| /|\ . |
| . . |
| ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
| [ method call] [method call] |
| . . |
| . \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler | | Outbound Handler M- | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler | | Outbound Handler M | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
+---------------+-----------------------------------+---------------+
| \|/
+---------------+-----------------------------------+---------------+
| | | |
| [ Socket.read() ] [ Socket.write() ] |
| |
+-------------------------------------------------------------------+ writeAndFlush流程:
Application --write--> ChannelOutboundBuffer --flush--> Socket发送缓冲区

六、Netty UDP Server is Single Thread Mode

note:不能阻塞IO线程,业务依靠业务线程池处理,否则Socket接收缓冲区溢出,会造成接收数据丢失,
数据可靠性问题,服务端设计方向利用 listen multi Network Interface 去处理,利用资源

netty 服务器端流程调度Flow笔记的更多相关文章

  1. Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

    Netty源码分析第一章:Netty启动流程   第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...

  2. Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

    Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...

  3. 题目:vbs批量开通工具,实现vbs开通的ux设计和流程调度

    题目:vbs批量开通工具,实现vbs开通的ux设计和流程调度 需求点:支持开通前检查(检查失败不允许开站),开通过程监控,开通后业务检验,失败后重新开通,支持部分站点开通(比如用户导入的模板中有10个 ...

  4. Netty启动流程剖析

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等,针对高性能RPC,一般都是基 ...

  5. Netty执行流程分析与重要组件介绍

    一.环境搭建 创建工程,引入Netty依赖 二.基于Netty的请求响应Demo 1.TestHttpServerHandle  处理器.读取客户端发送过来的请求,并且向客户端返回hello worl ...

  6. Spring Web Flow 笔记

    在Spring 中配置 Web Flow <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  7. openVswitch(OVS)源代码分析之工作流程(flow流表查询)

    原文链接: openVswitch(OVS)源代码分析之工作流程(flow流表查询)

  8. Netty writeAndFlush() 流程与异步

    Netty writeAndFlush()方法分为两步, 先 write 再 flush @Override public ChannelFuture writeAndFlush(Object msg ...

  9. Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化

    Netty源码分析第一章:  Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的 ...

随机推荐

  1. 015模块——起别名

    1.import起别名:通过as关键字可以给模块起别名: 模块名一旦起别名,原模块名就不能再使用 2.起别名的作用:①可以简化模块名字 import mmmmmmmmmmm3 as my_m3 pri ...

  2. awk 计算某一列的和

    awk 计算某一列的和 我需要通过nova list 显示所有虚拟机的cpu总和,即用awk计算某一列的综合 [root@control01 ~]# nla | awk -F '|' 'BEGIN{s ...

  3. django csrftoken

    CSRF(跨站请求伪造) 背景知识:浏览器在发送请求的时候,会自动带上当前域名对应的cookie内容,发送给服务端,不管这个请求是来源A网站还是其它网站,只要请求的是A网站的链接,就会带上A网站的co ...

  4. Python3开发过程常见的异常(最近更新:2019-04-26)

    持续更新中... 常见异常解决方案 1.Base Python3.7环境相关:https://www.cnblogs.com/dotnetcrazy/p/9095793.html 1.1.Indent ...

  5. HAOI2019+十二省联考 游记

    Day1 T1 考前还奶了一口不会考01Trie的,也就没有学,然后60分BOOM T2 不会SAM,告辞,30分滚粗 T3 传统实现题答?2p,2u,2g分别对应素数,莫比乌斯函数,原根?没看出来, ...

  6. JMeter 下载

    测试文件下载接口,jmeter返回的是字节流,所以jmeter本身是不支持将文件保存到本地的 怎么判断服务器有没有完全返回?response header头里面有一个content-lenth,添加断 ...

  7. Java基础 -- Collection和Iterator接口的实现

    Collection是描述所有序列容器(集合)共性的根接口,它可能被认为是一个“附属接口”,即因为要表示其他若干个接口的共性而出现的接口.另外,java.util.AbstractCollection ...

  8. jemter+ant+jenkins进行集成测试

    一下为我学习的一些笔记: 一.安装配置ant 安装地址:http://ant.apache.org/ 1.下载ant一路傻瓜式安装 2.配置ant环境变量:path下配置ant的bin路径 3.将jm ...

  9. C# 中的#if、#elif、#else、#endif等条件编译符号

    C#编译器遇到一个由#if和#endif包围起来的语句块时,会检查#if后面的符号是否已经被定义了,如果已经被定义,那么才会编译语句块之间的代码.而定义一个可以被#if测试的符号需要事先用#defin ...

  10. [Android] Android 手机下 仿 今日头条 新闻客户端

    利用一个月的时间,自学了 Android 开发 ,为了检验学习成果,特意 开发了这个  仿 今日头条 新闻客户端 AppNews 包括图文新闻+视频新闻+图片新闻 预览演示如下: 功能说明: 1)底部 ...