Channel的生命周期状态【状态转换将变为相应的事件,转发给ChannelPipeline中的ChannelHandler进行处理】
  ChannelUnregistered:Channel已经被创建,但还未注册到EventLoop
  ChannelRegistered:Channel已经被注册到了EventLoop
  ChannelActive:Channel处于活动状态(已经连接到它的远程节点)。它现在可以接收和发送数据了
  ChannelInactive:Channel没有连接到远程节点

ChannelHandler的生命周期【加入或者移除ChannelPipeline时调用这些方法,其有2个子类ChannelInboundHandler ChannelOutboundHandler】
  handlerAdded:当把ChannelHandler添加到ChannelPipeline中时被调用
  handlerRemoved:当从ChannelPipeline中移除ChannelHandler时被调用
  exceptionCaught:当处理过程中在ChannelPipeline中有错误产生时被调用

ChannelInboundHandler接口【入站】
  channelRegistered:当Channel已经注册到它的EventLoop并且能够处理I/O时被调用
  channelUnregistered:当Channel从它的EventLoop注销并且无法处理任何I/O时被调用
  channelActive:当Channel处于活动状态时被调用;Channel已经连接/绑定并且已经就绪
  channelInactive:当Channel离开活动状态并且不再连接它的远程节点时被调用
  channelReadComplete:当Channel上的一个读操作完成时被调用
  channelRead:当从Channel读取数据时被调用 【channelRead0是通过SimpleChannelInboundHandler的方法】
  ChannelWritability Changed:当Channel的可写状态发生改变时被调用。用户可以确保写操作不会完成得太快(以避免发生OutOfMemoryError)或者可以在Channel变为再次可写时恢复写入。可以通过调用Channel的isWritable()方法来检测Channel的可写性。与可写性相关的阈值可以通过Channel.config(). setWriteHighWaterMark()和    Channel.config().setWriteLowWater- Mark()方法来设置
  userEventTriggered:当ChannelnboundHandler.fireUserEventTriggered()方法被调用时被调用,因为一个POJO被传经了ChannelPipeline

ChannelOutboundHandler接口【出站 按需推迟操作或者事件(下载文件被暂停)】 channel->ChannelPipeline->ChannelOutboundHandler
  bind(ChannelHandlerContext,SocketAddress,ChannelPromise):当请求将Channel绑定到本地地址时被调用
  connect(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise):当请求将Channel连接到远程节点时被调用
  disconnect(ChannelHandlerContext,ChannelPromise):当请求将Channel从远程节点断开时被调用
  close(ChannelHandlerContext,ChannelPromise):当请求关闭Channel时被调用
  deregister(ChannelHandlerContext,ChannelPromise):当请求将Channel从它的EventLoop注销时被调用
  read(ChannelHandlerContext):当请求从Channel读取更多的数据时被调用
  flush(ChannelHandlerContext):当请求通过Channel将入队数据冲刷到远程节点时被调用
  write(ChannelHandlerContext,Object,ChannelPromise):当请求通过Channel将数据写到远程节点时被调用

资源泄漏:Netty提供了class ResourceLeakDetector 【java -Dio.netty.leakDetectionLevel=ADVANCED】

ChannelPipeline接口【每一个新创建的Channel都将会被分配一个新的ChannelPipeline】
ChannelPipeline保存了与Channel相关联的ChannelHandler;
ChannelPipeline可以根据需要,通过添加或者删除ChannelHandler来动态地修改;
ChannelPipeline有着丰富的API用以被调用,以响应入站和出站事件
ChannelHanlderContext【每加入一个Handler,就会绑定一个新建的ChannelHanlderContext】
可以通过调用ChannelHandlerContext上的pipeline()方法来获得被封闭的ChannelPipeline的引用。这使得运行时得以操作ChannelPipeline的ChannelHandler,我们可以利用这一点来实现一些复杂的设计。例如,你可以通过将ChannelHandler添加到ChannelPipeline中来实现动态的协议切换。
异常处理
ChannelHandler.exceptionCaught()的默认实现是简单地将当前异常转发给ChannelPipeline中的下一个ChannelHandler;
如果异常到达了ChannelPipeline的尾端,它将会被记录为未被处理;
要想定义自定义的处理逻辑,你需要重写exceptionCaught()方法。然后你需要决定是否需要将该异常传播出去。

每个EventLoop都由一个Thread支撑
EventLoopGroup bossGroup = new NioEventLoopGroup();//默认创建的Thread数值为Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

  

EventLoopGroup oiobossGroup = new OioEventLoopGroup();

  

AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel>
B extends AbstractBootstarp<B,C> 子类型是父类型的一个参数类型,可以在运行时返回实例的引用以支持链式方式的调用Bootstrap 与 ServerBootstrap方法

  Bootstrap group(EventLoopGroup):设置用于处理Channel所有事件的EventLoopGroup
  Bootstrap channel(Class<? extends C>)Bootstrap channelFactory(ChannelFactory<? extends C>):channel()方法指定了Channel的实现类。如果该实现类没提供默认的构造函数[7],可以通过调用channel- Factory()方法来指定一个工厂类,它将会被bind()方法调用
<T> Bootstrap option(ChannelOption<T> option,T value):设置ChannelOption,其将被应用到每个新创建的Channel的ChannelConfig。这些选项将会通过bind()或者connect()方法设置到Channel,不管哪个先被调用。这个方法在Channel已经被创建后再调用将不会有任何的效果。支持的ChannelOption取决于使用的Channel类型。
<T> Bootstrap attr(Attribute<T> key, T value):指定新创建的Channel的属性值。这些属性值是通过bind()或者connect()方法设置到Channel的,具体取决于谁最先被调用。这个方法在Channel被创建后将不会有任何的效果。
  Bootstrap handler(ChannelHandler):设置将被添加到ChannelPipeline以接收事件通知的ChannelHandler
  Bootstrap clone():创建一个当前Bootstrap的克隆,其具有和原始的Bootstrap相同的设置信息
  Bootstrap remoteAddress(SocketAddress):设置远程地址。或者,也可以通过connect()方法来指定它
  ChannelFuture connect():连接到远程节点并返回一个ChannelFuture,其将会在连接操作完成后接收到通知
  ChannelFuture bind():绑定Channel并返回一个ChannelFuture,其将会在绑定操作完成后接收到通知,在那之后必须调用Channel. connect()方法来建立连接

EventLoopGroup bossGroup = new NioEventLoopGroup();//处理channel所有事件的group
ServerBootstrap serverBootstrap = new ServerBootstrap();//创建和连接新的服务端channel
serverBootstrap.group(bossGroup, workerGroup)//提供处理新链接channel事件的事件组
.channel(NioServerSocketChannel.class)//指定所用的channel
.childHandler(new ChannelInitializer<SocketChannel>() {//设置处理channel事件和数据的handler
@Override
public void initChannel(SocketChannel ch) throws Exception {

  

ServerBootstrap bootstrap = new ServerBootstrap();  // ← --  创建ServerBootstrap 以创建ServerSocketChannel,并绑定它
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())// ← -- 设置EventLoopGroup,其将提供用以处理Channel 事件的EventLoop
.channel(NioServerSocketChannel.class)// ← -- 指定要使用的Channel 实现
.childHandler(// ← -- 设置用于处理已被接受的子Channel 的I/O 和数据的ChannelInboundHandler
new SimpleChannelInboundHandler<ByteBuf>() {
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Bootstrap bootstrap = new Bootstrap();// ← -- 创建一个Bootstrap类的实例以连接到远程主机
bootstrap.channel(NioSocketChannel.class).handler(// ← -- 指定Channel的实现
new SimpleChannelInboundHandler<ByteBuf>() { // ← -- 为入站I/O 设置ChannelInboundHandler
@Override
protected void channelRead0(
ChannelHandlerContext ctx, ByteBuf in)
throws Exception {
System.out.println("Received data");
}
});
bootstrap.group(ctx.channel().eventLoop());// ← -- 使用与分配给已被接受的子Channel 相同的EventLoop
connectFuture = bootstrap.connect(
new InetSocketAddress("www.123.com", 80)); // ← -- 连接到远程节点
} @Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {//当连接完成时,执行一些数据操作(如代理)
}
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));// ← -- 通过配置好的ServerBootstrap绑定该Server-SocketChannel
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bind attempt failed");
channelFuture.cause().printStackTrace();
}
}
});

  

Netty引导流程解读的更多相关文章

  1. linux引导流程

    本章重点: 1.linux引导流程 2.linux运行级别 3.linux启动服务管理 4.GRUB配置与应用 5.启动故障分析解决 linux启动流程 1.固件(fireware):固话在硬件上的程 ...

  2. (五)Linux引导流程解析

    目录 Linux引导流程 Linux运行级别 Linux启动服务管理 GRUB配置与应用 启动故障分析与解决 Linux引导流程 Linux系统引导流程如下图: 固件(Firmware)就是写入ERO ...

  3. 9.Linux系统引导流程

    一.Linux系统引导流程 当我们按下主机电源键的那时候开始,主板上的CMOS/BIOS模块将进行固件自检,以此检查各个硬件是否正确连接. 在Linux引导流程中,一般可以分为以下几个主要过程: 1. ...

  4. 平述factory reset ——从main system到重引导流程

    关于Android或linux的引导流程,网上大都是从开机开始讲述的,或者直接跳过bootloader引导阶段,直接从init进程开始说起.这里我从手机正常运行状态开始,到重启状态以及重启之后的状态略 ...

  5. Linux引导流程(第二版)

    Linux引导流程 柱面,0磁头,1扇区 如图:] 进入这一步骤的目的是[通常,PID是随机分配的,但是init特殊,可以通过命令:ps -el | more 查看],Linux系统中init名义上可 ...

  6. 5linux引导流程解析

    课程大纲  Linux引导流程  Linux运行级别  Linux启动服务管理  GRUB配置与应用  启动故障分析与解决     常用固件设置 安全设置 可引导介质列表 可引导介质搜索顺序 ...

  7. linux 启动引导流程

    课程大纲: Linux引导流程 Linux运行级别 Linux启动服务管理 GRUB配置与应用 启动故障分析与解决 系统引导流程 1.固件firmware(CMOS(固化在硬件上的程序与硬件统称)/B ...

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

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

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

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

随机推荐

  1. IOS7升级攻略

    1) Select the main view, set the background color to black (or whatever color you want the status ba ...

  2. Scrapy爬虫框架 基础

    1< scrapy的安装 命令行安装 pip install scrapy <常见错误是缺少 wim32api 安装win32api pip install pywin32 <还有就 ...

  3. vue02 过滤器、计算和侦听属性、vue对象的生命周期、阻止事件冒泡和刷新页面

    3. Vue对象提供的属性功能 3.1 过滤器 过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中. 定义过滤器的方式有两种. 3.1.1 使用Vue.fil ...

  4. Oracle 【基 本 操 作】

    1.日期时间 select SYSDATE from DUAl; select TO_CHAR(SYSDATE, 'YYYY-MM-DD') from DUAL; select TO_CHAR(SYS ...

  5. [luogu4728 HNOI2009] 双递增序列 (dp)

    传送门 Solution 前几天刚做了类似题,这种将一个序列拆分为两个单调序列的题一般都是设\(dp[i]\)表示i为一个单调序列的末尾时,另一个序列的末尾是多少 然后应用贪心的思想,在这道题中就是让 ...

  6. SqlServer大数据的分区方案

    这里介绍的是大数据量的维护日志的分区解决方案: 每个月1张数据表,1个分组文件.31个分区(按每天1个分区).... 为了日后维护方便,直接删除旧的日志数据文件就可以,而不需要去做分区压缩. --用的 ...

  7. 洛谷 1486 郁闷的出纳员【Treap】

    [题意概述] 要求维护一个序列支持以下操作: 1,插入元素x: 2,把序列的所有元素加上x: 3,把序列的所有元素减去x,同时低于一个给定的下限的元素马上被删除: 4,询问序列中第k大的元素. [题解 ...

  8. springboot优雅关机

    Spring boot 2.0 之优雅停机  rabbitGYK 关注 2018.05.20 18:41* 字数 1794 阅读 2638评论 0喜欢 22 spring boot 框架在生产环境使用 ...

  9. Oracle GoldenGate从oracle db 到非oracle db的初始化数据同步的方法

    非oracle db以 sqlserver为样例说明: 我的思路 A :oracle db 生产  B: oracle db 中间机 C: sqlserver db 目的端 A-> B-> ...

  10. WCF学习笔记——不支持内容类型 text/xml; charset=utf-8

    我在使用WCF的时候,客户端运行报错: 不支持内容类型 text/xml; charset=utf-8 原因是WCF服务做了修改.刷新客户端的服务引用,问题消失 =================== ...