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框架。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode刷题笔记题解(C++):LCR 174. 寻找二叉搜索树中的目标节点

思路&#xff1a;二叉搜索树的中序遍历是有序的从大到小的&#xff0c;故得出中序遍历的结果&#xff0c;即要第cnt大的数为倒数第cnt的数 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeN…

HNU-数据挖掘-实验1-实验平台及环境安装

数据挖掘课程实验实验1 实验平台及环境安装 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验1 实验平台及环境安装实验背景实验目标实验步骤1.安装虚拟机和Linux平台&#xff0c;熟悉Ubuntu环境。2.在Linux平台上搭建Python平台&#xff0c;并安装…

Macos数据库管理软件:Navicat Premium for Mac 16.3.5中文版

Navicat Premium 16 for Mac是一款强大的数据库管理和开发工具&#xff0c;支持多种数据库系统&#xff0c;如MySQL、Oracle、SQL Server等。它提供了直观的用户界面和丰富的功能&#xff0c;使用户能够轻松地创建、管理和维护数据库。 软件下载&#xff1a;Navicat Premium fo…

【C++语言1】基本语法

前言 &#x1f493;作者简介&#xff1a; 加油&#xff0c;旭杏&#xff0c;目前大二&#xff0c;正在学习C&#xff0c;数据结构等&#x1f440; &#x1f493;作者主页&#xff1a;加油&#xff0c;旭杏的主页&#x1f440; ⏩本文收录在&#xff1a;再识C进阶的专栏&#x1…

鸿蒙开发案列一

1、开发需求 案例app一打开是“Hello world” 界面&#xff0c;开发者点击“Hello world”变成“Hello ArkUI”’ 2、源代码 Entry Component struct Hello {State person_name: string Worldbuild() {Row() {Column() {Text(Hello this.person_name).fontSize(50).fontWei…

市场复盘总结 20240119

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 昨日主题投资 连板进级率 11/39 28.2% 二进三&#xff1a; 进级率低 43% 最常用的二种方法&#xff1a; 方…

【面试】测试/测开(ING3)

190. 栈和堆在内存管理上的区别 栈 1&#xff09; 栈是由系统自动分配和回收的内存。 2&#xff09;栈的存储地址是由高地址向低地址扩展的。 3&#xff09;栈是一个先进后出的结构。 4&#xff09;栈的空间大小是一个在编译时确定常数&#xff0c;即栈的大小是有限制的&#x…

仰暮计划|“她告诉我,大部分时间她都是一个家庭主妇,负责照料家务和小孩,但她从来没有停止她对知识的追求”

我来到河南省开封市兰考县南北庄村内一个宁静而温馨的小院子&#xff0c;那里居住着一位九十多岁的高龄老人&#xff0c;她就是张奶奶。张奶奶是村里的一位高龄老人&#xff0c;拥有着丰富的人生经历。我对她的故事非常充满好奇&#xff0c;所以特地来到张奶奶的家中&#xff0…

测试开发基础 | 计算机网络篇(二):物理层与数据链路层

【摘要】 计算机网络知识是自动化测试等技术基础&#xff0c;也是测试面试必考题目。霍格沃兹测试学院特别策划了本系列文章&#xff0c;将带大家一步步夯实计算机网络的基础知识。由于物理层知识在互联网软件研发工作中用到的并不多&#xff0c;所以可以仅做一个简单的了解。物…

理解PCIE设备透传

PCIE设备透传解决的是使虚拟机直接访问PCIE设备的技术&#xff0c;通常情况下&#xff0c;为了使虚拟机能够访问Hypervisor上的资源&#xff0c;QEMU&#xff0c;KVMTOOL等虚拟机工具提供了"trap and emulate"&#xff0c; Virtio半虚拟化等机制实现。但是这些实现都…

MySQL之数据库DDL

文章目录 MySQL数据库基本操作数据定义DDL对数据库的常用操作创建表修改表格式结构 MySQL数据库基本操作 首先我们先了解SQL的语言组成&#xff0c;他分为四个部分 数据定义语言&#xff08;DDL&#xff09;数据操纵语言&#xff08;DML&#xff09;数据控制语言&#xff08;…

three.js从入门到精通系列教程004 - three.js透视相机(PerspectiveCamera)滚动浏览全景大图

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>three.js从入门到精通系列教程004 - three.js透视相机&#xff08;PerspectiveCamera&#xff09;滚动浏览全景大图</title><script src"js/three.js"&g…

Python 自动化办公:一键批量生成 PPT

Stata and Python 数据分析 一、导读 在实际工作中&#xff0c;经常需要批量处理Office文件&#xff0c;比如需要制作一个几十页的PPT进行产品介绍时&#xff0c;一页一页地制作不仅麻烦而且格式可能不统一。那么有什么办法可以一键生成PPT呢&#xff1f;Python提供的pptx 包…

mysql生成最近24小时整点时间临时表

文章目录 生成最近24小时整点生成最近30天生成最近12个月 生成最近24小时整点 SELECT-- 每向下推1行, i比上次减去1b.*, i.*,DATE_FORMAT( DATE_SUB( NOW(), INTERVAL ( -( i : i - 1 ) ) HOUR ), %Y-%m-%d %H:00 ) AS time FROM-- 目的是生成12行数据( SELECTa FROM( SELECT…

【Python从入门到进阶】47、Scrapy Shell的了解与应用

接上篇《46、58同城Scrapy项目案例介绍》 上一篇我们学习了58同城的Scrapy项目案例&#xff0c;并结合实际再次了项目结构以及代码逻辑的用法。本篇我们来学习Scrapy的一个终端命令行工具Scrapy Shell&#xff0c;并了解它是如何帮助我们更好的调试爬虫程序的。 一、Scrapy Sh…

CTF CRYPTO 密码学-5

题目名称&#xff1a;山岚 题目描述&#xff1a; 山岚 f5-lf5aa9gc9{-8648cbfb4f979c-c2a851d6e5-c} 解题过程&#xff1a; Step1&#xff1a;根据题目提示栅栏加密 分析 观察给出的密文发现有f、l、a、g等字符有规律的夹杂的密文中间&#xff0c;看出都是每3个字符的第1…

P9232 [蓝桥杯 2023 省 A] 更小的数

[蓝桥杯 2023 省 A] 更小的数 终于本弱一次通关了一道研究生组别的题了[普及/提高−] 一道较为简单的双指针题,但一定有更好的解法. 题目描述 小蓝有一个长度均为 n n n 且仅由数字字符 0 ∼ 9 0 \sim 9 0∼9 组成的字符串&#xff0c;下标从 0 0 0 到 n − 1 n-1 n−1&a…

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

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

【Linux】vim 操作指令详解

Linux 1 what is vim &#xff1f;2 vim基本概念3 vim的基本操作 &#xff01;3.1 vim的快捷方式3.1.1 复制与粘贴3.1.2 撤销与剪切3.1.3 字符操作 3.2 vim的光标操作3.3 vim的文件操作 总结Thanks♪(&#xff65;ω&#xff65;)&#xff89;感谢阅读下一篇文章见&#xff01;…

Git教程学习:09 Git分支

文章目录 1 分支的简介2 分支的相关操作2.1 分支的创建2.2 分支的切换2.3 分支的合并2.4 分支推送到远程2.5 分支的删除2.6 分支的重命名 3 分支开发工作流程3.1 长期分支3.2 短期分支 1 分支的简介 几乎所有的版本控制系统都以某种形式支持分支。使用分支意味着我们可以把我们…