一个Netty程序始于Bootstrap类,Bootstrap类是Netty提供的一个可以通过简单配置来设置或“引导”程序的一个重要的类。Netty中设计了Handlers来处理特定的"event"和设置Netty中的事件,从而来处理多个协议和数据。ChannelInboundHandler用来接收消息。Netty提供ChannelInitializer用来配置Handler, ChannelInitializer通过ChannelPipeline来添加ChannelHandler。ChannelInitializer自身也是一个ChannelHandler,再添加完所有handlers之后会自动从ChannelPipeline中删除自己。

  所有Netty都是基于ChannelPipeline。ChannelPipeline和EventLoop和EventLoopGroup密切相关。

  Netty所有的IO操作都是异步执行的。Netty使用Futures和ChannelFutures来达到目的。Future注册一个监听,当操作成功或失败时会通知。ChannelFuture封装的是一个操作的相关信息,操作被执行时会立刻返回ChannelFuture。

  Netty是一个非阻塞,事件驱动和网络框架。Netty实际上是用多线程处理IO事件。

  当注册一个Channel时,Netty将这个Channel绑定到一个EventLoop,在Channel生命周期内总是被绑定到一个EventLoop。

  Bootstrap

    引导有两种类型:一种是用于客户端的Bootstrap(也适用于DatagramChannel),另一种是用于服务端的ServerBootstrap。

    Bootstrap和ServerBootstrap的差异:Bootstrap用来连接远程主机,有1个EventLoopGroup;ServerBootstrap用来绑定本地端口,有2个EventLoopGroup。

    ServerBootstrap监听在服务器监听一个端口轮询客户端的“Bootstrap”或DatagramChannel是否连接服务器。通常需要先调用bind()后再调用connect()进行连接。之后使用Channel的bind()返回ChannelFuture中。

    bootstarp/applications使用一个单例EventLoopGroup,而ServerBootstrap使用了2个EventLoopGroup。一个ServerBootstrao可以认为有两个channels组,第一个组包含一个单例ServerChannel,代表持有一个绑定了本地端口的socket,第二组包含所有Channel,代表服务器已接受了连接。

    EventLoopGroup可以包含多个EventLoop,每个Channel绑定一个EventLoop,很多Channel会共享一个EventGroup。这意味着在一个Channel保持EventLoop繁忙会禁止其他Channel绑定到相同的EventGroup。

   

  Channel Handlers and Data Flow

    Channel Handler是一段执行业务逻辑处理数据的代码,他们来来往往的通过ChannelPipeline。ChannelHandler是定义一个handler的父接口。

    Netty有两个方向的数据流。若数据是从用户应用程序到远程主机则是“出站(outbound)”,若数据从远程主机到用户应用则是“入站(inbound)”、为了使数据从一端到另一端,一个或多个ChannelHandler将以某种方式操作数据,这些ChannelHandler会在程序的“引导”阶段添加ChannelPipeline中,并且被添加的顺序将决定处理数据的顺序。ChannelPipeline的作用可以理解为用来管理ChannelHandler的一个容器,每个ChannelHandler处理各自的数据,处理完后将转换的数据放到ChannelPipeline中交给下一个ChannelHandler继续处理,直到最后一个ChannelHandler处理完成。

    在ChannelPipeline中,若消息被读取或有任何其他的入站事件,消息将从ChannelPipeline的头部开始传递给第一个ChannelInboundHandler,这个ChannelInboundHandler可以处理该消息或将消息传递到下一个ChannelInboundHandler中,一旦在ChannelPipeline中没有剩余的ChannelInboundHandler后,ChannelPipeline就知道消息已被所有的Handler处理完成了。任何出站事件或写入将从ChannelPipeline的尾部开始,并传递到最后一个ChannelOutboundHandler。ChannelOutboundHandler可以传递消息到下一个Handler或自己处理消息。

    Netty提供了抽象的事件基类ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter。每个都提供了在ChannelPipeline中通过调用相应的方法将事件传递给下一个Handler的方法的实现。

    当一个ChannelHandler添加到ChannelPipeline中时获得一个ChannelHandleContext。通常是安全的获得这个对象的引用,但当一个数据协议不正确时,这个对象可以在之后用来获取底层通道,因此要用它来read/write消息,因此消息通道将会保留。因此Netty发送消息有两种方法:直接写入通道或写入ChannelHandlerContext对象。这两种方法的区别为:直接写入通道导致处理消息从ChannelPipeline的尾部开始;写入ChannelHandlerContext对象导致处理消息从ChannelPipeline的下一个handler开始。

  

    自定义ChannelHandler需要继承编码/解码适配器类中的一个。Netty有ChannelHandlerAdapter,ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter三个适配器。

    应用程序只需要扩展SimpleChannelInboundHandler<I>,通过重写父类的方法可以获得一个ChannelHandlerContext的引用,它们接受一个ChannelHandlerContext参数。处理程序关注的主要方法是“channelRead0(ChannelHandlerContext ctx, I msg)”。可以添加ChannelHandler到ChannelPipeline中指定一个EventExecutorGroup,EventExecutorGroup会获得一个EventExecutor,EventExecutor将执行ChannelHandler的所有方法。EventExecutor将使用不同的线程和释放EventLoop。

    

Netty核心概念的更多相关文章

  1. Netty In Action中文版 - 第三章:Netty核心概念

            在这一章我们将讨论Netty的10个核心类.清楚了解他们的结构对使用Netty非常实用.可能有一些不会再工作中用到.可是也有一些非经常常使用也非常核心,你会遇到. Bootstrap ...

  2. Netty核心概念(10)之内存管理

    1.前言 之前的章节已经将启动demo中能看见的内容都分析完了,Netty的一个整体样貌都在第8节线程模型最后给的图画出来了.这些内容解释了Netty为什么是一个异步事件驱动的程序,也解释了Netty ...

  3. Netty核心概念(8)之Netty线程模型

    1.前言 第7节初步学习了一下Java原本的线程池是如何工作的,以及Future的为什么能够达到其效果,这些知识对于理解本章有很大的帮助,不了解的可以先看上一节. Netty为什么会高效?回答就是良好 ...

  4. Netty核心概念(7)之Java线程池

    1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...

  5. Netty核心概念(6)之Handler

    1.前言 本节介绍Netty中第三个重要的概念——Handler,这个在前两节都提到了,尤其是Channel和Handler联系紧密.handler本身的设计非常简单,但是所起到的作用却很大,Nett ...

  6. Netty核心概念(5)之Channel

    1.前言 上一节讲了Netty的第一个关键启动类,启动类所做的一些操作,和服务端的channel固定的handler执行过程,谈到了不管是connect还是bind方法最终都是调用了channel的相 ...

  7. Netty核心概念(4)之Bootstrap

    1.前言 第三节介绍了Netty的一些基本概念,此节介绍Netty的第一个概念Bootstrap——启动类.Netty中服务端和客户端的启动类是不一样的,这个不要搞错了,类都在bootstrap包下. ...

  8. Netty核心概念(9)之Future

    1.前言 第7节讲解JAVA的线程模型中就说到了Future,并解释了为什么可以主线程可以获得线程池任务的执行后结果,变成一种同步状态.秘密就在于Java将所有的runnable和callable任务 ...

  9. 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!

    前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...

随机推荐

  1. R12 查询EBS用户相关SQL(转)

    https://www.cnblogs.com/quanweiru/p/4869697.html http://hutianci.iteye.com/blog/934921 --R12查询EBS在线用 ...

  2. 七、持久层框架(MyBatis)

    一.MyBatis学习 平时我们都用JDBC访问数据库,除了自己需要写SQL,还要操作Connection,Statement,ResultSet这些. 使用MyBatis,只需要自己提供SQL语句, ...

  3. ActiveMQ 事务和XA

    1. 客户端怎样显式地使用事务? producer 开启事务(代码片段): ActiveMQSession session = (ActiveMQSession)connection.createSe ...

  4. Python3各种进制之间的转换方法

    一.2/8/10/16进制互转 1.1 2/8/10/16进制赋值 # 二进制赋值以0b打头 a = 0b1000 # 八进制赋值以0o打头,第一个是数字0第二个是字母o b = 0o1100 # 十 ...

  5. samba服务断开某个用户 samba客户端断开自动登录

    结论: 方式二成功率更高,方式一有时候会失败. 方式一:windows命令行 删除链接 1. net use 查看连接情况 2. net use * /del 3. 如果不行 重启电脑 方式二: 删除 ...

  6. python图片识别

    python 图像处理模块1. 安装 pytesseract模块是会自动安装Pillow模块.pillow 为标准图像处理库 手册地址 http://pillow-cn.readthedocs.io/ ...

  7. 微信小程序web-view使用测试总结

    1.后台配置业务域名. 2.在开发者工具的web-view组件中绑定业务域名. 3.点击开发者工具的详情按钮,选择调试基础库高版本,如果不设置,有可能绑定的业务域名内容不显示. 4.如果是公众号上的内 ...

  8. python文件管理

    文件没有修改操作,修改的方式为打开文件--读取文件--内存中编辑文件--将内容写入文件 打开文件方式 with open('a.txt','w') as f: #操作系统自动关闭文件 f.write( ...

  9. jsp下载excel文件

    jsp下载excel文件的的实现方法很多,今天也遇到这个问题,乱敲了一阵,终于搞定了,记下来和朋友们分享吧. 假设需要下载excel文件的jsp页面名为:down.jsp 对应的后台action名为: ...

  10. zookeeper:springboot+dubbo配置zk集群并测试

    1.springboot配置zk集群 1.1:非主从配置方法 dubbo: registry: protocol: zookeeper address: ,, check: false 1.2:主从配 ...