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整体架 ...
随机推荐
- MRBS开源会议室预订系统安装
MRBS系统官方网址 https://mrbs.sourceforge.io/ 最近在找一份开源的会议室预订系统,找了很多种,ASP,PHP的,测试发现MRBS无疑是最好的.开源社区对其介绍如下:M ...
- 数据结构与算法之PHP查找算法(哈希查找)
一.哈希查找的定义 提起哈希,我第一印象就是PHP里的关联数组,它是由一组key/value的键值对组成的集合,应用了散列技术. 哈希表的定义如下: 哈希表(Hash table,也叫散列表),是根据 ...
- Nginx+Tomcat集群配置
Nginx+Tomcat集群配置 一台虚拟机作为Nginx服务 两太虚拟机配置Tomcat+jdk环境 Nginx测试 启动: cd usr/local/nginx/sbin ./nginx ---& ...
- 抓包工具Charles的简单使用
一.Charles破解 下载安装及破解方法: 1.下载charles并安装 云盘下载地址:Windows 64bit 32bit 2.安装后先打开Charles一次(Windows版可以忽略此步 ...
- C++LeetCode:: Container With Most Water
本来写的题目不是这个,而是字符串匹配,考虑了很多情况写了很久最后看了solution,发现可以用动态规划做.感觉被打击到了,果断先放着重新写一个题,后面心情好了再重新写吧,难过.每天都要被LeetCo ...
- 设计模式:java及spring观察者模式(有利于代码解耦)
http://www.cnblogs.com/softidea/p/5716870.html 什么是ApplicationContext? 它是Spring的核心,Context我们通常解释为上下文环 ...
- python3.7 安装
python3.7 安装 下载安装 cd /usr/localwget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgztar -xvf ...
- anglar cli的 rxjs_1.of is not a function
按照官网敲例子遇到 rxjs_1.of is not a function import { Observable,of } from 'rxjs'; 改为 import { Observable} ...
- 【基础】火狐和谷歌在Selenium3.0上的启动(二)
参考地址:http://www.cnblogs.com/fnng/p/5932224.html https://github.com/mozilla/geckodriver [火狐浏览器] 火狐浏览器 ...
- linux内核initcall
include/linux/init.h #define pure_initcall(fn) __define_initcall(fn, 0) #define core_initcall(fn) __ ...