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整体架 ...
随机推荐
- Leetcode 1002. 查找常用字符
1002. 查找常用字符 显示英文描述 我的提交返回竞赛 用户通过次数301 用户尝试次数324 通过次数303 提交次数480 题目难度Easy 给定仅有小写字母组成的字符串数组 A,返回列表 ...
- JAVA正则表达式:Pattern、Matcher、String
java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包.它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表 ...
- linux 逻辑卷管理 /dev/mapper/VolGroup-lv_root 100%调整分区大小
1.解决过程 # df -h // 查看分区 # umount /home // 取消挂载 # e2fsck -f /dev/mapper/VolGroup-lv_home // 分区检测 ...
- jQuery-全屏滚动插件【fullPage.js】API 使用方法总结
jQuery-全屏滚动插件[fullPage.js]API 使用方法总结 jQuery-全屏滚动插件fullPage.js使用方法总结 作者github及下载地址:https://github.c ...
- Oracle12c中容错&性能新特性之表空间组
1. 简介 表空间组可以使用户消耗来自多个表空间的临时表空间.表空间组有如下特点: 1) 至少包含一个表空间.表空间组中包含的最大表空间数没有限制. 2) 和表空间共 ...
- 前端框架之Vue.js
前言: 前端主流框架有Vue.react.angular,目前比较火因为Vue比较容易学习,运营起来比较快速: Vue是什么呢? 是一个基于MVVM架构的,前端框架: 如果你之前已经习惯了用jQuer ...
- ActiveMQ queue 分页
分页:即获取部分数据,queue按页从message cursor读取消息,然后分发给consumer. 页大小: public abstract class BaseDestination impl ...
- vue+vue-resource+vue-cookie随笔
vue-resource http拦截器interceptors: Vue.http.interceptors.push(function(request, next) {...} V-cookie: ...
- listener.ora和tnsnames.ora格式解析
listener.ora是oracle数据库服务端的监听配置文件,包括协议.IP地址和端口等内容:tnsnames.ora是oracle数据库客户端的连接配置文件,也是对应的协议.IP地址和端口等内容 ...
- git Please move or remove them before you can merge.
git clean -d -fx "" 其中 x -----删除忽略文件已经对git来说不识别的文件 d -----删除未被添加到git的路径中的文件 f -----强制运行