Netty核心概念
一个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核心概念的更多相关文章
- Netty In Action中文版 - 第三章:Netty核心概念
在这一章我们将讨论Netty的10个核心类.清楚了解他们的结构对使用Netty非常实用.可能有一些不会再工作中用到.可是也有一些非经常常使用也非常核心,你会遇到. Bootstrap ...
- Netty核心概念(10)之内存管理
1.前言 之前的章节已经将启动demo中能看见的内容都分析完了,Netty的一个整体样貌都在第8节线程模型最后给的图画出来了.这些内容解释了Netty为什么是一个异步事件驱动的程序,也解释了Netty ...
- Netty核心概念(8)之Netty线程模型
1.前言 第7节初步学习了一下Java原本的线程池是如何工作的,以及Future的为什么能够达到其效果,这些知识对于理解本章有很大的帮助,不了解的可以先看上一节. Netty为什么会高效?回答就是良好 ...
- Netty核心概念(7)之Java线程池
1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...
- Netty核心概念(6)之Handler
1.前言 本节介绍Netty中第三个重要的概念——Handler,这个在前两节都提到了,尤其是Channel和Handler联系紧密.handler本身的设计非常简单,但是所起到的作用却很大,Nett ...
- Netty核心概念(5)之Channel
1.前言 上一节讲了Netty的第一个关键启动类,启动类所做的一些操作,和服务端的channel固定的handler执行过程,谈到了不管是connect还是bind方法最终都是调用了channel的相 ...
- Netty核心概念(4)之Bootstrap
1.前言 第三节介绍了Netty的一些基本概念,此节介绍Netty的第一个概念Bootstrap——启动类.Netty中服务端和客户端的启动类是不一样的,这个不要搞错了,类都在bootstrap包下. ...
- Netty核心概念(9)之Future
1.前言 第7节讲解JAVA的线程模型中就说到了Future,并解释了为什么可以主线程可以获得线程池任务的执行后结果,变成一种同步状态.秘密就在于Java将所有的runnable和callable任务 ...
- 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!
前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...
随机推荐
- MySQL 处理海量数据时一些优化查询速度方法
1.应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by设计的列上建立 ...
- 安装docker No package docker available
安装docker 时候出现以下问题 yum -y install dockerLoaded plugins: fastestmirrorDetermining fastest mirrors * ba ...
- Vue + webpack 项目配置化、接口请求统一管理
准备工作 需求由来: 当项目越来越大的时候提高项目运行编译速度.压缩代码体积.项目维护.bug修复......等等成为不得不考虑而且不得不做的问题. 又或者后面其他同事接手你的模块,或者改你的bug ...
- pandas报错处理:TypeError: Empty 'DataFrame': no numeric data to plot
Tushare返回的是pandas的DataFrame格式,但是执行以下代码时报错:TypeError: Empty 'DataFrame': no numeric data to plot impo ...
- Java反序列化修复方案
1)下载与当前大版本相同的commons-collections包(原来是3.2.x就替换为3.2.2,原来是4.x就替换为4.4.1) 下载链接:http://commons.apache.org/ ...
- Unity中Text中首行缩进两个字符和换行的代码
1.首行缩进两个字符 txt.text=“\u3000\u3000” + str: 2.首行缩进两个字符 将输入法换成全角的,在Text属性面板中添加空格即可. 3.换行 “\n” 补充 Uni ...
- mybatis generator工具的使用
mybatis反转数据库的配置文件: generatorConfig.xml: <?xml version="1.0" encoding="UTF-8"? ...
- OOP⑸
1.封装: 继承: extends java只支持单根继承!(一个类只能有一个直接的父类) 是代码重用的一种方式! 将子类共有的属性和方法提取到父类中去! Object:超类/基类==>java ...
- SignalR NuGet程序包
最近公司有一个边看直播边聊天的需求,直播好搞,直接用腾讯的小直播,组装推流和播放地址,把推流地址拿出去就OK,只要一推流,就可以使用播放地址观看直播,看完后通过webclient去异步下载直播的视频到 ...
- windows7环境下java jdk的配置
第一步: 肯定是先下载好java jdk啦~~ 网址在这里:http://www.oracle.com/technetwork/java/javase/downloads/index.html 打开这 ...