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. IP地址、子网掩码、默认网关是什么意思?

    (一)  问题解析 001.   问:  IP地址,子网掩码,默认网关,DNS服务器,有什么区别呀?我知道没有IP地址就不能上网,我也知道没设DNS就不能上外网,可它们都有什么功能,有什么区别呢?还有 ...

  2. bugku web web5

    JSPFUCK??????答案格式CTF{**} http://123.206.87.240:8002/web5/ 字母大写 jspfuck这不是骂人吗,怎么回事啊? ·点进去看见有一个可以输入的框, ...

  3. 关于【jq插件开发】

    很详细,原文链接:https://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html#commentform和https://www.cnblogs ...

  4. [LOJ3088][GXOI/GZOI2019]旧词——树链剖分+线段树

    题目链接: [GXOI/GZOI2019]旧词 对于$k=1$的情况,可以参见[LNOI2014]LCA,将询问离线然后从$1$号点开始对这个点到根的路径链修改,每次询问就是对询问点到根路径链查询即可 ...

  5. python3.7安装pylint

    python3.7安装pylint之"setuptools"版本错误 借鉴:错题集(已解决):pyinstaller报错ModuleNotFoundError: No module ...

  6. P2447 [SDOI2010]外星千足虫 (高斯消元)

    题目 P2447 [SDOI2010]外星千足虫 解析 sol写到自闭,用文字描述描述了半个小时没描述出来,果然还是要好好学语文 用高斯消元求解异或方程组. 因为 \(奇数\bigoplus奇数=偶数 ...

  7. 【学习笔记】TensorFlow

    1. tf.Graph().as_default() 的作用 首先看官网上的解释: 再看博主 Joanna-In-Hdu&Hust 对此比较通俗易懂的解释(https://www.cnblog ...

  8. 一加X 手机变砖过程

    很久无使用的一台手机,因需要获得ROOT权限而使用kingroot这款软件,无法获得root权限.而这个软件会导致手机无法进入ERCOVERY模式,后果是你没有办法刷入别的rom,而kingroot的 ...

  9. 【一本通1329:【例8.2】细胞&&洛谷P1451 求细胞数量】

    1329:[例8.2]细胞 [题目描述] 一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数.如: 阵列 4 10 023 ...

  10. vue+axios实现文件下载

    功能:点击导出按钮,提交请求,下载excel文件: 第一步:跟后端童鞋确认交付的接口的response header设置了 axios({ method: 'post', url: 'api/user ...