Netty篇章(1)—— 核心原理介绍

终于进入到Netty框架的环节了,前面介绍了大量的Java-NIO的内容,核心的内容Selector、Channel、Buffer、Reactor掌握了,那么学起来Netty也是水到渠成的事情。如果没有掌握前面的内容那么学Netty会非常吃力,下面讲解Netty核心原理与概念。

Netty是一个Java NIO客户端/服务器框架,是一个为了快速开发可维护的高性能、高可扩展的网络服务器和客户端程序而提供的异步事件驱动基础框架和工具。如果要开发一个网络通信模块,那么Netty是首选,知名的Dubbo、Zookeeper、RocketMQ 网络通信模块全都是Netty实现的,我发现阿里的分布式框架网络通信模块很喜欢使用Netty作为网络通信框架。Netty的目标之一,是使通信开发可以做到“快速和轻松”。使用Netty除了能“快速和轻松”的开发TCP/UDP等自定义协议的通信程序之外,使用Netty还可以做到“快速和轻松”地开发应用层协议的通信程序,如FTP, SMTP, HTTP以及其他的传统应用层协议。 总之一句话,Netty是一款高性能、高可扩展性、能进行快速扩展以支持不同协议通信、完成不同业务处理的网络通信框架。

在使用Netty前,首先需要考虑一下JDK的版本, 建议使用JDK1.8。然后是Netty的版本,建议使用Netty 4.0以上的版本:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.66.Final</version>
</dependency>

Netty中的Reactor反应器

前面一篇Reactor的文章不知道强调了多少次Reactor的概念,如果还不清楚,这里再次强调:Reactor就是一个单独的线程执行的Selector组件接受客户端IO事件的实例。粗暴理解成 Reactor = Thread + Selector。在Netty的实现中Reactor角色叫做NioEventLoop(事件循环),它就是封装了Selector组件对象和Thread线程实例。NioEventLoop类有两个重要的成员属性:一个是Thread线程类的成员,一个是Java NIO选择器的成员属性。 NioEventLoop的继承关系和主要的成员属性,如下图所示。

在这里插入图片描述

NioEventLoop和前面章节讲到反应器实现,在思路上是一致的:一个NioEventLoop拥有一个Thread线程,负责一个Java NIO Selector选择器的IO事件轮询。其实可以简单吧Reactor理解成Selector就行,在Netty中, EventLoop反应器和Channel通道的关系是啥呢?理论上来说,一个EventLoop反应器和NettyChannel通道是一对多的关系:一个反应器可以注册成千上万的通道。

在这里插入图片描述

后面系列文章将结合Channel、Handler等知识通过代码进行介绍,目前只要理解了NioEventLoop就是Reactor反应器即可,理解Reactor是什么就行。

Netty中的Channel通道

前面也讲过NIO中的Channel通道,反应器模式和通道紧密相关,反应器的查询和分发的IO事件都来自于Channel通道组件。Netty中不直接使用Java NIO的Channel通道组件,对Channel通道组件进行了自己的封装。Netty实现了一系列的Channel通道组件,为了支持多种通信协议,换句话说,对于每一种通信连接协议, Netty都实现了自己的通道。Netty中不直接使用Java NIO的Channel通道组件,对Channel通道组件进行了自己的封装。Netty实现了一系列的Channel通道组件,为了支持多种通信协议,换句话说,对于每一种通信连接协议, Netty都实现了自己的通道。

Netty中常见的通道类型如下:

  • NioSocketChannel:异步非阻塞TCP Socket传输通道。
  • NioServerSocketChannel:异步非阻塞TCP Socket服务器端监听通道。
  • NioDatagramChannel:异步非阻塞的UDP传输通道
  • OioSocketChannel:同步阻塞式TCP Socket传输通道。
  • OioServerSocketChannel:同步阻塞式TCP Socket服务器端监听通道。
  • OioDatagramChannel:同步阻塞式UDP传输通道。

不论是那种通道类型,在主要的API和使用方式上和NioSocketChannel类基本是相同的,更多是底层的传输协议不同,而Netty帮大家极大的屏蔽了传输差异,所以,如果没有特殊情况,的很多通道都可以参考NioSocketChannel通道。Netty只是做了封装,底层还是Java-NIO的Channel通道,继承关系如下:

在这里插入图片描述

Netty中的Handler处理器

在Netty中, EventLoop反应器内部有一个线程负责Java NIO选择器的事件的轮询,然后进行对应的数据分发。这里和经典Reactor模式的区别: Netty的IO事件分发(Dispatch) ,属于EventLoop的内部分发, 并没有直接将IO事件分发到EventLoop的外部。如何理解?假设发生了IO读事件,那么EventLoop将输入的数据读取到ByteBuf中。EventLoop读取到数据之后,再将输入数据分发到通道的Pipeline, 此次数据分发的目标,才是Netty的Handler处理器。也就是说IO事件还是自己读,只是将读到的数据放到Pipeline中,供程序员对数据进行处理,而这个处理也就是Handler处理器类要做的事情。Netty的Handler处理器分为两大类:第一类是ChannelInboundHandler入站处理器;第二类是ChannelOutboundHandler出站处理器,二者都继承了ChannelHandler处理器接口。

Ok@! 很多读者读到这开始懵逼了,什么出站入站嘛!我连Handler都不知道是啥呢?你又引入了什么出站处理器和入站处理器,还有什么乱七八糟的Pipeline是啥? 我是懂读者心里状态的,因为我学习的时候也是带着这些疑问硬啃完的,相信我,继续往下看你的疑问将柳暗花明。

前面介绍过Selector反应器,其中有个Selector选择器,如果客户端A已经连接了服务器,此时向服务器发送数据,那么对于服务器而言将产生一个IO读事件,通过Selector的select方法将查询到这个读事件,然后接下来对这个读事件进行处理。而对IO事件的处理就是处理器,处理器在前面我们讲解Reactor反应器中没有特意定义为一个类,而只是一个处理方法。而在Netty中,如果我们需要对已经查询到的IO事件进行处理,我们需要重写处理器类的一些读数据方法或者写数据方法,而这些处理器又分为ChannelOutboundHandler出站处理器和ChannelInboundHandler入站处理器。

那么什么是入站处理器呢?什么是出站处理器呢?Netty的出入站处理指的的API调用的方向是应用层开发维度的,你可以理解为当发生了IO读事件会被EventLoop查询到,然后分发到内部的IO事件处理方法, 之后把读取到的客户端数据发射到通道的Pipeline, 这里还没有讲解Pipeline的概念,你可以理解为一个数据流水线。然后这个数据就会在数据流水线中往下传播,其中就有ChannelInboundHandler入站处理器,处理器的方法read将被调用读取流进来的数据,然后程序员就可以在这里实现对数据的处理,例如解码、显示到界面,然后保存到数据库等操作。IO事件触发了,然后EventLoop读取数据把数据往Pipeline发送,其中经过入站处理器。这不就和废水处理厂一样的逻辑吗?数据就是废水,废水入站进行处理,处理完之后再向下传播或者终止。

明白了上述入站处理器之后,出站处理器就不难理解了吧!Netty中的出站处理具体指的是什么呢?指的是从ChannelOutboundHandler处理器到通道的某次IO操作,例如,在应用程序完成业务处理后,可以通过ChannelOutboundHandler出站处理器将处理的结果写入底层通道。它的最常用的一个方法就是write()方法,把数据写入到通道。最直观的理解就是通过出站处理器将服务器的数据进行处理,例如从数据库中查询,然后编码,然后再将处理的数据写到底层Channel通道中发送给客户端。Netty中的出站处理,不仅仅包括write()方法,还包括从Handler处理器到底层Channel的方向的其他操作。 Netty出站和Java NIO的出站在概念上有细微的区别,其实不需要分的这么清楚,入站就是读客户端的数据进行处理,出站就是服务器的数据处理完后发送出去,就这样理解。

无论是入站还是出站, Netty都提供了各自的默认适配器实现:

  • ChannelInboundHandler的默认实现为ChannelInboundHandlerAdapter (入站处理适配器) ;
  • ChannelOutboundHandler的默认实现为ChanneloutBoundHandlerAdapter(出站处理适配器)。

这两个默认的通道处理适配器,分别实现了基本的入站操作和出站操作功能。如果要实现自己的业务处理器,不需要从零开始去实现处理器的接口,只需要继承通道处理适配器即可。

NettyPipeline通道处理流水线

学习到现在,我们知道了Reactor是和Channel进行绑定的,但是上面的Handler和Channel如何建立连接关系呢?Netty设计了一个特殊的组件,叫做ChannelPipeline(通道处理流水线),它像一条管道,将一个通道的多个Handler处理器实例串在一起,形成一条流水线。ChannelPipeline(通道流水线)的默认实现,实际上被设计成一个双向链表。所有的Handler处理器实例被包装成了双向链表的节点,被加入到了ChannelPipeline(通道流水线)中。一个 Netty 通道拥有一个 ChannelPipeline 通道流水线类型的成员属性,该属性的名称叫做 pipeline。以入站处理为例。每一个来自通道的IO数据,都会进入一次ChannelPipeline通道流水线。在进入第一个Handler处理器后,这个IO数据将按照既定的从前往后次序,在流水线上不断地向后流动,流向下一个Handler处理器。如果后面没有其他的入站处理器,这就意味着这个IO数据在此次流水线中的处理结束了。如果在中间需要终止流动,可以选择将当前处理器的结果,不再交给下一个Handler处理器,流水线的执行也被截断了。

Netty的通道流水线与普通的流水线不同, Netty的流水线不是单向的,而是双向的,而普通的流水线基本都是单向的。 Netty是这样规定的:入站处理器Handler的执行次序,是从前到后,或者说从头到尾;出站处器Handler的执行次序,是从后到前。总之, IO事件在流水线上的执行次序,与IO事件的类型是有关系的 。除了流动的方向与IO操作类型有关之外,流动过程中所经过的处理器类型,也是与IO操作的类型有关。入站类型的IO操作, 只能从Inbound入站处理器类型的Handler向后传播;出站的IO操作, 只能从Outbound出站处理器类型的Handler向前传播。

在这里插入图片描述

到这里,Netty的各个组件就基本上介绍完毕,后面几期文章就会从代码的实现来讲解如何使用Netty框架。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/342158.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python - argparse模块

python中的argparse模块&#xff0c;用于命令后参数解析&#xff0c;方便测试&#xff0c;是python中自带的模块。 可以自动生成帮助文档&#xff0c;和使用手册。而且当用户在执行程序的时候&#xff0c;输入无效的参数时&#xff0c;会给出对应的错误信息。 使用方法&#…

C++学习笔记——指针

1&#xff0c;指针的基本概念 指针的作用&#xff1a;可以通过指针间接访问内存 内存的编号是从0开始记录的&#xff0c;一般用十六进制数字表示可以利用指针变量保存地址 上图中的p就是a变量的指针&#xff0c;也可以记作*a 2&#xff0c;指针变量的定义和使用 指针变量定…

k8s使用ingress实现应用的灰度发布升级

v1是1.14.0版本nginx ,实操时候升级到v2是1.20.0版本nginx&#xff0c;来测试灰度发布实现过程 一、方案&#xff1a;使用ingress实现应用的灰度发布 1、服务端&#xff1a;正常版本v1&#xff0c;灰度升级版本v2 2、客户端&#xff1a;带有请求头versionv2标识的请求访问版…

头条文章采集ChatGPT4.0改写软件环境配置教程步骤

大家好&#xff0c;我是淘小白~ 下面给大家整理一下&#xff0c;ChatGPT4.0改写软件环境配置教程 下面是我们拿到的环境配置软件&#xff0c;分别是&#xff1a;117版本的谷歌浏览器&#xff0c;谷歌浏览器驱动&#xff0c;notepad&#xff08;用于打开config.ini&#xff0c…

由于找不到msvcp140.dll无法继续执行的5种解决方法

在计算机系统中&#xff0c;如果未能成功找到或加载msvcp140.dll这个动态链接库文件&#xff0c;可能会引发一系列运行问题和功能障碍。msvcp140.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序来说&#xff0c;它是至关重…

ASP.NET Core 高级之使用Redis缓存

阅读本文你的收获 了解Redis基本作用及其使用场景学会安装Redis服务端和客户端及简单的命令行操作学习在ASP.NET Core WebAPI项目中如何操作Redis缓存 一、Redis介绍 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键…

全国各城市绿地及绿化面积数据,shp/excel格式,2020-2022年

基本信息. 数据名称: 全国各城市绿地及绿化面积数据 数据格式: Shp、excel 数据时间: 2020-2022年 数据几何类型: 面 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省份名称2city城市名称4city_dm城市…

通过浏览器URL地址,5分钟内渗透你的网站!很刑很可拷!

今天我来带大家简单渗透一个小破站&#xff0c;通过这个案例&#xff0c;让你深入了解为什么很多公司都需要紧急修复各个中间件的漏洞以及进行URL解析拦截等重要操作。这些措施的目的是为了保护网站和系统的安全性。如果不及时升级和修复漏洞&#xff0c;你就等着被黑客攻击吧&…

使用Python自动化操作手机,自动执行常见任务,例如滑动手势、呼叫、发送短信等等

使用Python自动化操作手机,自动执行常见任务,例如滑动手势、呼叫、发送短信等等。 此自动化脚本将帮助你使用 Python 中的 Android 调试桥 (ADB) 自动化你的智能手机。下面我将展示如何自动执行常见任务,例如滑动手势、呼叫、发送短信等等。 您可以了解有关 ADB 的更多信息,…

测量USB接口信号眼图质量

此处只描述High&#xff0d;Speed模式信号质量的测试方法&#xff0c;Full&#xff0d;Speed测试方法可参考High&#xff0d;Speed测试方法。测试前连接好电路&#xff0c;对于USB 2.0 Host设备&#xff0c;差分探头TDP3500尽量靠近芯片信号输出地方&#xff0c;并注意极性不要…

[Tomcat] [最全] 目录和文件详解

打开tomcat的解压之后的目录可以看到如下的目录结构&#xff1a; Bin bin目录主要是用来存放tomcat的命令&#xff0c;主要有两大类&#xff0c;一类是以.sh结尾的&#xff08;linux命令&#xff09;&#xff0c;另一类是以.bat结尾的&#xff08;windows命令&#xff09;。 …

RFID智能产线设计管理方案

在传统的制造企业中&#xff0c;日常管理主要集中在产品管理、质量管理、仓库管理、移动资产管理、现场人员管理、车队管理等方面&#xff0c;而传统的人工采集和手工输入方式存在准确性不足和错误率高的问题&#xff0c;手工输入只能定时进行&#xff0c;导致生产计划只能按周…

工业智能网关储能物联网应用实现能源的高效利用及远程管理

储能电力物联网是指利用物联网技术和储能技术相结合&#xff0c;实现对电力系统中各种储能设备的智能管理和优化控制。随着可再生能源的不断发展和应用&#xff0c;电力系统面临着越来越大的电力调度和储能需求而储能电力物联网的出现可以有效解决这一问题&#xff0c;提高电力…

保姆级CISP报考攻略,让你不再迷茫

信息安全领域越来越火&#xff0c;想要在这个行业闯出一片天&#xff1f;CISP认证就是你的“敲门砖”&#xff01;想知道如何顺利考取这个超牛的证书吗&#xff1f;下面就带你一起探索保姆级CISP报考流程&#xff01;&#x1f389; &#x1f393;报考条件&#x1f393; 学历专业…

年末怒赚一笔,程序员快码住!趁热接单

元旦已过&#xff0c;龙年将至。 有钱没钱&#xff0c;回家过年。 话说回来&#xff0c;年关将至&#xff0c;农历的2023即将落下帷幕。天气渐寒&#xff0c;你的钱包是否也让你心生寒意&#xff1f;年初立下的赚钱flag是否优雅地实现了? 如果flag都倒了&#xff0c;你先别…

csdn发布文章审核一直未通过解决办法

搞了很久的confluence&#xff0c;踩了很多坑终于弄好了&#xff0c;却一直显示审核不通过&#xff0c;给笔记一顿狂改还是不通过&#xff0c;一直说是版权问题就很让人起疑&#xff0c;最后问了客服才知道&#xff0c;现在开始查版权问题&#xff0c;所以我给confluence笔记中…

Git仓库里嵌着别的仓库导致出现问题

例如这样&#xff0c;git仓库里面有箭头&#xff0c;且仓库打开是一个空仓库。 解决问题的方法 1.到子仓库路径下&#xff0c;使用ls -a指令可以看到文件夹下有一个.git文件夹。 我们使用rm -rf <子仓库路径>/.git删除每个子仓库下面的.git文件夹。 2.执行git rm --cache…

把握好这5个阶段,快速成交优质外贸客户

要想快速成交一个有潜力的优质客户往往需要经历五个阶段。这五个阶段分别是&#xff1a;“获联”、“筛选”、“入野”、“破局”、“快速成交”。 01 获联 我们的第一步工作&#xff0c;就是需要主动或者被动去吸引客户&#xff0c;把客户引进来。将客户引进来的方式有…

基本语法和 package 与 jar

3.基本语法 1.输入输出 // 导入 java.util 包中的 Scanner 类 import java.util.Scanner;// 定义名为 ScannerExample 的公共类 public class ScannerExample {// 主方法&#xff0c;程序的入口点public static void main(String[] args) {// 创建 Scanner 对象&#xff0c;用…