netty的常用类以及执行流程

总体概述

类关系

给ServerBootstrap配置两个EventLoopGroup,一个建立连接,一个处理网络io。
EventLoopGroup给EventLoop分配线程。
在 Netty 中,EventLoop 通过不断轮询 Selector 来检测 Channel 上发生的事件,当 Channel 上的事件到达时,EventLoop 会将事件传入 相应的Channel 的成员变量 ChannelPipeline 中,经过所有ChannelHandler 来处理这些事件。

执行流程

当一个事件传入时,会判断是连接事件还是其他事件,如果是连接事件交给eventloopgroup中的建立连接的eventloop,其中的nioserverchannel会处理连接事件,如果是其他事件,那么会交给处理网络io的eventloop中的channel,eventloop轮询发现有channel有事件需要执行,那么就在这个eventloop线程中调用channel的channelpipeline,执行相应的channelhander。

其中:eventloopgroup可以指定eventloop的数量,eventloopgroup就像线程池一样,会负载均衡地分配建立连接的channel给不同的eventloop。

Netty的NIO的常用概念

ServerBootstrap

ServerBootstrap 是一个用于帮助配置和启动服务器的类。它是Netty中用于创建服务器端应用程序的主要入口点

Channel

在计算机网络编程中,Channel(通道) 是一种抽象概念,代表着数据在源和目标之间的连接。通道是数据传输的通路,通道的两端可以是网络连接、文件、套接字等。

Channel类型

  • 文件通道 (FileChannel): 用于对文件进行读写操作。
  • 套接字通道 (SocketChannel, ServerSocketChannel, DatagramChannel): 用于进行网络通信,这些通道是基于 Java NIO 提供的 SelectableChannel 的实现。它们通常通过 EventLoop、ChannelPipeline 和自定义的处理器来实现异步和事件驱动的网络编程。

SocketChannel 是用于 TCP 客户端通信的通道。
它可以连接到远程服务器,并进行双向通信。
SocketChannel 支持阻塞和非阻塞的模式。

ServerSocketChannel 是用于 TCP 服务器通信的通道。
它监听客户端的连接请求,并创建一个新的 SocketChannel 用于与客户端通信。
ServerSocketChannel 也支持阻塞和非阻塞的模式。

DatagramChannel 是用于 UDP 通信的通道。
UDP 是面向消息的,DatagramChannel 支持无连接的数据报传输。
DatagramChannel 与 SocketChannel 相比更轻量,适用于不需要可靠性传输的场景。

  • 管道 (Pipe.SinkChannel, Pipe.SourceChannel): 用于在两个线程之间进行通信。

通道(Channel)和流(Stream)有一些相似之处,但也有一些关键的区别。

相似之处

数据传输: 通道和流都用于在程序和数据源/目的地之间进行数据传输。
字节流和字符流: 通道和流都可以用于处理字节数据(字节流)和字符数据(字符流)。

区别
阻塞非阻塞

通道: 通道通常是非阻塞的,可以使用选择器(Selector)来实现多路复用,从而监控多个通道的状态。
流: 流通常是阻塞的,即在读写操作时,如果没有数据可读或没有足够的空间可写,程序会阻塞等待。

双向性

通道: 通道是双向的,可以支持读和写操作。例如,文件通道 (FileChannel) 可以同时支持读取和写入文件。
流: 流通常是单向的,即要么是输入流(从数据源读取数据),要么是输出流(向数据源写入数据)。需要使用两个流才能实现双向传输。

底层实现

通道: 通道通常直接映射到操作系统的底层 I/O 操作,因此性能可能更好。在 Java NIO 中,通道与 Selector 搭配使用,可以实现非阻塞 I/O。
流: 流通常是在通道的基础上建立的高级抽象,提供了更高层次的 API。在 Java IO 中,流是基于字节或字符的 I/O 操作。

直接缓冲区

在 Java NIO 中,通道(Channel)支持直接缓冲区(DirectBuffer),这使得数据可以直接从内存中的缓冲区传输到通道,或者从通道直接传输到内存中的缓冲区,而不需要中间步骤。
通道: 通道支持直接缓冲区,允许将数据直接从内存中的缓冲区传输到通道,而不需要中间步骤。
流: 流通常不支持直接缓冲区,需要通过中间的数组或缓冲区来进行数据传输。

通常有两种类型的缓冲区:堆缓冲区(Heap Buffer)和直接缓冲区(Direct Buffer)。
堆缓冲区: 在堆上分配的缓冲区,数据位于Java堆内存中。这是默认的缓冲区类型。
直接缓冲区: 直接分配在操作系统的内存中,而不是Java堆中。直接缓冲区可以通过 ByteBuffer.allocateDirect() 方法来创建。
直接缓冲区的优势之一是可以通过 FileChannel 的 transferTo() 和 transferFrom() 方法直接在通道之间传输数据,而无需通过中间缓冲区。
当使用非直接缓冲区(Heap Buffer)时,通常的操作是先将数据从通道读取到堆缓冲区,然后再进行其他操作。同样,当写入时,数据也会从堆缓冲区写入到通道。

Channel内部有成员变量unsafe和Pipeline,unsafe是Channel网络io的底层实现,ChannelPipeline 负责管理该 Channel 上的处理器链。

SelectionKey

简单源码

public interface SelectionKey {// 表示对读事件感兴趣static final int OP_READ = 1;// 表示对写事件感兴趣static final int OP_WRITE = 4;// 表示对连接事件感兴趣static final int OP_CONNECT = 8;// 表示对接受事件感兴趣static final int OP_ACCEPT = 16;// 返回与此键关联的通道SelectableChannel channel();// 返回选择器Selector selector();// 返回表示感兴趣的事件的操作集合int interestOps();// 设置感兴趣的事件的操作集合SelectionKey interestOps(int ops);// 返回表示已准备就绪的操作的操作集合int readyOps();。。。。。。。}

ChannelPipline

ChannelPipline是ChannelHandler的容器,维护了一个Handler的链表和迭代器。
当事件发生时,在eventloop的中它会被传递给ChannelPipeline,然后从头到尾依次经过每个ChannelHandler。
使用ServerBootstrap启动服务器netty会自动为每个Channel创建一个独立的pipepline,我们只要将想用的ChannelHandle加入即可。

ChannelHandler

事务的执行是通过channelpipeline,连接,读写等网络io操作是由channelpipeline的Handler执行(Handler中调用unsafe的方法)。

Eventloop

Eventloop作为NIO框架的Reactor线程,其中有一个Select的成员变量,用来实现多路复用。
Channel需要注册到EventLoop的多路复用器上,EventLoop本质上就是处理网络读写任务的Reactor线程,在Neety中,它还可以用力啊处理定时任务和用户自定义NioTask任务。
Eventloop的run方法是其核心,伪代码:

public void run() {while (true) {try {// 阻塞直到有事件发生int readyChannels = selector.select();// 处理所有已经就绪的事件if (readyChannels > 0) {Set<SelectionKey> selectedKeys = selector.selectedKeys();for (SelectionKey key : selectedKeys) {if (key.isAcceptable()) {// 处理连接事件// 处理连接事件的逻辑} else if (key.isReadable()) {// 处理读事件// 处理读事件的逻辑} else if (key.isWritable()) {// 处理写事件// 处理写事件的逻辑}// 可以处理更多类型的事件,根据实际需要扩展}selectedKeys.clear();}// 处理任务队列中的任务while (!tasks.isEmpty()) {Runnable task = tasks.poll();task.run();}} catch (IOException e) {// 处理异常情况e.printStackTrace();}}

EventGroup

EventLoopGroup 负责管理一组 EventLoop 实例,每个 EventLoop 实例与一个线程相关联。
EventLoopGroup 提供了 shutdownGracefully() 方法,用于优雅地关闭所有关联的 EventLoop。
服务端启动时候,创建了两个NioEventLoopGroup,他们是两个独立的Reactor线程池,一个用来接收客户端的TCP连接,另一个用来处理IO相关的读写操作,或者执行系统Task,定时任务Task等。
接收客户端请求的线程池职责

  1. 接收客户端的TCP连接,初始化Channel参数。
  2. 将链路状态变更事件通知给ChannelPipeline。

处理IO操作的线程池的职责

  1. 异步读取通信数据包,发送读事件给ChannelPipeline;
  2. 异步发送消息,通过发送读事件给ChannelPipeline。
  3. 执行系统Task和定时Task;

Promise和Future

Promise 是 Future 的扩展,它继承了 Future 接口。它们都代表了一个尚未完成的操作,可以用于异步操作的结果通知和处理。
区别:

可写性: Future 是只读的,一旦创建就不能被修改。而 Promise 是可写的,可以通过它来设置操作的结果。
操作结果的设置: 在使用 Future 时,你只能等待其完成,而不能主动设置操作的结果。而在使用 Promise 时,你可以主动设置操作的结果,因此它提供了更灵活的控制。
用途: Future 通常用于表示一个异步操作的结果,而 Promise 用于表示一个异步操作的开始和结果的产生。在很多情况下,你会首先创建一个 Promise,然后将它转化为一个 Future 对象,传递给其他部分的代码,使得它们可以等待异步操作的结果。

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

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

相关文章

考研C语言刷题基础篇之数组(一)

目录 第一题&#xff1a;用数组作为参数实现冒泡排序 不用函数的冒泡排序 冒泡排序原理&#xff1a; 错误的数值传参冒泡排序 错误的原因 就是什么是数组名 正确的数组传参的冒泡排序 数组的地址和数组首元素的地址的区别 第一题&#xff1a;用数组作为参数实现冒泡排…

npm ERR! code CERT_HAS_EXPIRED errno CERT_HAS_EXPIRED

npm ERR! code CERT_HAS_EXPIRED 和 npm ERR! errno CERT_HAS_EXPIRED 都是指npm 在尝试连接到 npm 仓库时遇到了 SSL 证书过期的问题。这可能是由于您使用的 npm 仓库的证书已过期&#xff0c;或者您的系统时间不正确。 解决此问题的方法如下 1.关闭 npm 的 SSL 验证 通常在…

Docker网络配置与自定义IP容器通信

目录 前言 一、docker网络配置 1. bridge 虚拟网桥 2. host 网络模式 3. none 网络模式 4. 自定义container网络模式 二、自定义IP容器通信 1. 自定义IP 2. 创建所需容器&#xff08;mysql&#xff0c;tomcat&#xff09; 3. 准备项目资源 4. 构建Nginx实现负载均衡…

this指向问题以及修改函数的this指向方法

1、什么是this this表示对象 取决于函数调用&#xff08;this表示对象>当前对象>当前环境对象>函数运行时环境对象&#xff09; this就是函数运行时所在的环境对象&#xff08;取决于函数调用>不同场合&#xff0c;this有不同的值&#xff09; 函数的不同使用场…

rsync命令常用参数详解

1、语法 Usage: rsync [OPTION]… SRC [SRC]… DEST or rsync [OPTION]… SRC [SRC]… [USER]HOST:DEST or rsync [OPTION]… SRC [SRC]… [USER]HOST::DEST or rsync [OPTION]… SRC [SRC]… rsync://[USER]HOST[:PORT]/DEST or rsync [OPTION]… [USER]HOST:SRC [DEST] or r…

PyTorch深度学习实战(32)——DCGAN详解与实现

PyTorch深度学习实战&#xff08;32&#xff09;——DCGAN详解与实现 0. 前言1. 模型与数据集分析1.1 模型分析1.2 数据集介绍 2. 构建 DCGAN 生成人脸图像小结系列链接 0. 前言 DCGAN (Deep Convolutional Generative Adversarial Networks) 是基于生成对抗网络 (Convolution…

el-form动态检验无法生效问题

<el-form-item label"状态&#xff1a;"prop"zt"class"bitianxian"><el-select v-model"ruleForm.zt"placeholder"请选择"change"emptyztXM()"><el-option v-for"(item,index) in ZTdata&quo…

PWN入门Protostar靶场Stack系列

Protostar靶场地址 https://exploit.education/protostar/溢出 源码分析 #include <stdlib.h> #include <unistd.h> #include <stdio.h>int main(int argc, char **argv) {volatile int modified; //定义一个变量char buffer[64]; //给…

Git 入门精讲

我们为什么要学习git&#xff1f; 就当下的发展而言&#xff0c;只要你从事开发就一定会接触git。作为最强大的分布式版本控制器&#xff0c;git 与 svn 有着本质上的区别。 Git是一种分布式版本控制系统&#xff0c;每个开发者都可以在本地维护完整的代码库&#xff0c;可以离…

c++ 加密与解密代码(普通加密 + 凯撒加密 + 图灵来了都解不开的加密)

当你和你的好朋友聊天的时候&#xff0c;你们的聊天内容很容易就被看出来&#xff0c;那么小天狼星这边可以给到一些建议~~ 一、用另一种语言 通常来说&#xff0c;使用除中文和其他常用语言外的语言是一个优秀的选择&#xff01; 例如&#xff1a;乌伯克语、阿亚帕涅科语。 …

智能泊车,再上热搜

编者按&#xff1a;相比于行车&#xff0c;低速可控场景&#xff0c;更有利于泊车功能快速迭代。同时&#xff0c;对于部分消费者来说&#xff0c;泊车智能化也是加分项。 智能泊车赛道&#xff0c;正在重新成为各路势力争夺的焦点。而上一次“高潮”&#xff0c;要追溯到2018年…

开源客户沟通平台Chatwoot账号激活问题

安装docker docker-compose 安装git clone https://github.com/chatwoot/chatwoot 下载之后根目录有一个docker-compose.production.yaml将其复制到一个目录 重命名 docker-compose.yaml 执行docker-compose up -d 构建 构建之后所有容器都安装好了 直接访问http://ip:3…

护眼台灯怎么选——明基、书客、孩视宝实测横评

最近护眼台灯的热度真是不小&#xff0c;许多博主纷纷推荐。考虑到孩子即将放寒假&#xff0c;市场上的产品也是五花八门&#xff0c;于是我决定认真研究一下&#xff0c;找出其中的水货和宝藏产品。我挑选了市场上口碑较好的3款产品进行深入评估&#xff0c;主要从照度、显色指…

Revit二次开发 设置材质

设置此处材质&#xff0c;需要在材质浏览器中创建材质&#xff0c;根据材质名字设置此材质。 代码如下&#xff1a; Material material new FilteredElementCollector(doc).OfClass(typeof(Material)).FirstOrDefault(x > x.Name "窗框") as Material; Element…

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹 1.安裝pip install google-generativeai 2.至 gemini pro 取 api key 3.撰寫如下文章:(方法一) import json import requests import base64 import streamlit as st 讀取圖片檔案&#xff0c;並轉換成 Base64 編…

ES6对象新增了哪些扩展?

ES6&#xff08;ECMAScript 2015&#xff09;为JavaScript中的对象引入了一些新的扩展功能。以下是一些主要的ES6对象扩展&#xff1a; 对象字面量的增强&#xff08;Object Literal Enhancements&#xff09;&#xff1a; ES6允许在对象字面量中更简洁地定义属性和方法。您可以…

Android SeekBar 进度条圆角

先看下效果图&#xff1a; 之前&#xff1a; 优化后&#xff1a; 之前的不是圆角是clip切割导致的 全代码&#xff1a; <SeekBarandroid:layout_width"188dp"android:layout_height"wrap_content"android:background"null"android:focusa…

程序员裁员潮

裁员对程序员的影响可以是相当大的&#xff0c;特别是在技术变革的时期。以下是一些可能的影响&#xff1a; 失业&#xff1a;当公司裁员时&#xff0c;程序员可能会失去他们的工作。这将导致失业风险的增加&#xff0c;特别是如果他们在特定行业或领域内专门从事工作。 就业机…

风速预测 | Python基于CEEMDAN-CNN-Transformer+ARIMA的风速时间序列预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 CEEMDAN-CNN-TransformerARIMA是一种用于风速时间序列预测的模型&#xff0c;结合了不同的技术和算法。收集风速时间序列数据&#xff0c;并确保数据的质量和完整性。这些数据通常包括风速的观测值和时间戳。CEEMDAN分…

php 面向对象与反序列

目录 1.类和对象 2.序列化 3.反序列化 1.类和对象 <?php//类 class cl {var $name "fly"; // 类属性//函数function _destruct(){echo $this->name;}//函数function eat() {echo apple;} }//对象 $a new cl(); echo $a->name.<br>; //直接调用…