当前位置: 首页 > news >正文

WebRTC服务质量(10)- Pacer机制(02) RoundRobinPacketQueue

WebRTC服务质量(01)- Qos概述
WebRTC服务质量(02)- RTP协议
WebRTC服务质量(03)- RTCP协议
WebRTC服务质量(04)- 重传机制(01) RTX NACK概述
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(06)- 重传机制(03) NACK找到真正的丢包
WebRTC服务质量(07)- 重传机制(04) 接收NACK消息
WebRTC服务质量(08)- 重传机制(05) RTX机制
WebRTC服务质量(09)- Pacer机制(01) 流程概述
WebRTC服务质量(10)- Pacer机制(02) RoundRobinPacketQueue
WebRTC服务质量(11)- Pacer机制(03) IntervalBudget
WebRTC服务质量(12)- Pacer机制(04) 向Pacer中插入数据

一、前言:

RoundRobinPacketQueue 是Pacer模块当中一个非常重要的循环队列模块,主要目的是在多流场景中,根据每个流的 优先级 以及流内的 RTP 包的 入队顺序类型 和其他因素,动态决定数据包的发送顺序。

二、类关系图:

2.1、类图:

在这里插入图片描述

关键部分加了注释,便于理解:

  1. 多流支持: 每个流按 SSRC(Synchronization Source Identifier,同步信源标识符)进行区分,每个流维护独立的优先级队列。
  2. 多级优先级调度: 不同流间按优先级调度(基于 StreamPrioKey),单个流内的包按严格的队列顺序管理。
  3. 静态与动态属性结合: 例如,属性包括每个包的优先级(priority)、入队时间(enqueue_time)、重传标志、带宽开销等。
  4. 分组调度: 使用轮询(Round-Robin)机制,从不同流根据流的权重和优先级选取包发送,提高音频、视频和反馈等多种类型数据的实时性。

2.2、重要成员关系:

在这里插入图片描述

  1. stream_priorities当中存放StreamPrioKey和ssrc对应关系;
  2. streams当中存放ssrc和Stream的对应关系;
  3. 这样就建立了StreamPrioKey和Stream之间的关系;
  4. 反过来,也可以通过Stream当中的priority_it找到stream_priorities当中的某一项;

小结下:重要成员变量的功能

成员变量功能
streams_保存所有流,键是流的 ssrc,每条流存有独立队列和优先级信息。
stream_priorities_将所有流按照 StreamPrioKey 排列,用于实现流间优先级调度。
enqueue_times_一个多重集合,保存所有包的入队时间,便于快速找到最早入队的包时间。
size_packets_size_分别记录队列中包的个数和总字节数,动态调整。
transport_overhead_per_packet_计算包传输的额外开销(如包头)。
time_last_updated_用于统计队列的更新时间,辅助计算入队和等待时间等。

三、重要函数:

3.1、Push

Push 会根据包的优先级、流的权重、总队列大小,以及包的类型等,将包插入到对应的流(Stream)队列,并更新其他与队列状态关联的元数据。总体思路如下:

处理一个新包时:

  1. 确定该包所属的流,如果不存在该流,则创建一个 Stream 对象。
  2. 将包包装成为 QueuedPacket 并插入到流的优先级队列。
  3. 更新流的优先级键 StreamPrioKey,并在 stream_priorities_ 中重新排序。
  4. 更新队列元数据(如队列包大小、队列时间等)。
void RoundRobinPacketQueue::Push(int priority,Timestamp enqueue_time,uint64_t enqueue_order,std::unique_ptr<RtpPacketToSend> packet) {RTC_DCHECK(packet->packet_type().has_value());if (size_packets_ == 0) {// Single packet fast-path.single_packet_queue_.emplace(QueuedPacket(priority, enqueue_time, enqueue_order,enqueue_times_.end(), std::move(packet)));UpdateQueueTime(enqueue_time);single_packet_queue_->SubtractPauseTime(pause_time_sum_);size_packets_ = 1;size_ += PacketSize(*single_packet_queue_);} else {MaybePromoteSinglePacketToNormalQueue();Push(QueuedPacket(priority, enqueue_time, enqueue_order,enqueue_times_.insert(enqueue_time), std::move(packet)));}
}void RoundRobinPacketQueue::Push(QueuedPacket packet) {auto stream_info_it = streams_.find(packet.Ssrc());if (stream_info_it == streams_.end()) {stream_info_it = streams_.emplace(packet.Ssrc(), Stream()).first;stream_info_it->second.priority_it = stream_priorities_.end();stream_info_it->second.ssrc = packet.Ssrc();}Stream* stream = &stream_info_it->second;if (stream->priority_it == stream_priorities_.end()) {RTC_CHECK(!IsSsrcScheduled(stream->ssrc));stream->priority_it = stream_priorities_.emplace(StreamPrioKey(packet.Priority(), stream->size), packet.Ssrc());} else if (packet.Priority() < stream->priority_it->first.priority) {stream_priorities_.erase(stream->priority_it);stream->priority_it = stream_priorities_.emplace(StreamPrioKey(packet.Priority(), stream->size), packet.Ssrc());}if (packet.EnqueueTimeIterator() == enqueue_times_.end()) {packet.UpdateEnqueueTimeIterator(enqueue_times_.insert(packet.EnqueueTime()));} else {UpdateQueueTime(packet.EnqueueTime());packet.SubtractPauseTime(pause_time_sum_);size_packets_ += 1;size_ += PacketSize(packet);}stream->packet_queue.push(packet);
}
  • 从streams中找packet所属的Ssrc的stream,如果没有,则在streams中插入一项;
  • 查看stream的priority_it是否等于stream_priorities_的end()
    • 如果相等,则在stream_priorities_中插入一项;
    • 否则,如果新包的优先高(注意,优先级数值越小表示优先级越高),则更新其ssrc对应队列的优先级;
  • 更新队列总时长;
  • 入队时间减去暂停时间(一般不会有暂停);
  • 队列总包数+1;
  • 队列总字节大小 = 包的负载大小+Padding大小;
  • 插入到stream中的packet_queue中;

3.2、Pop

Pop 会轮询不同的流并从当前优先级最高的流中取出一个包发送,同时维护包的发送顺序。总体思路如下:

  1. 调用 GetHighestPriorityStream 获取当前优先级最高的流。
  2. 从该流的优先级队列(PriorityPacketQueue)中取出队首包,并更新流的状态(如剩余大小、时间等)。
  3. 如果该流没有剩余包,删除对应的流优先级键。
std::unique_ptr<RtpPacketToSend> RoundRobinPacketQueue::Pop() {if (single_packet_queue_.has_value()) {RTC_DCHECK(stream_priorities_.empty());std::unique_ptr<RtpPacketToSend> rtp_packet(single_packet_queue_->RtpPacket());single_packet_queue_.reset();queue_time_sum_ = TimeDelta::Zero();size_packets_ = 0;size_ = DataSize::Zero();return rtp_packet;}RTC_DCHECK(!Empty());Stream* stream = GetHighestPriorityStream();const QueuedPacket& queued_packet = stream->packet_queue.top();stream_priorities_.erase(stream->priority_it);// Calculate the total amount of time spent by this packet in the queue// while in a non-paused state. Note that the |pause_time_sum_ms_| was// subtracted from |packet.enqueue_time_ms| when the packet was pushed, and// by subtracting it now we effectively remove the time spent in in the// queue while in a paused state.TimeDelta time_in_non_paused_state =time_last_updated_ - queued_packet.EnqueueTime() - pause_time_sum_;queue_time_sum_ -= time_in_non_paused_state;RTC_CHECK(queued_packet.EnqueueTimeIterator() != enqueue_times_.end());enqueue_times_.erase(queued_packet.EnqueueTimeIterator());// Update |bytes| of this stream. The general idea is that the stream that// has sent the least amount of bytes should have the highest priority.// The problem with that is if streams send with different rates, in which// case a "budget" will be built up for the stream sending at the lower// rate. To avoid building a too large budget we limit |bytes| to be within// kMaxLeading bytes of the stream that has sent the most amount of bytes.DataSize packet_size = PacketSize(queued_packet);stream->size =std::max(stream->size + packet_size, max_size_ - kMaxLeadingSize);max_size_ = std::max(max_size_, stream->size);size_ -= packet_size;size_packets_ -= 1;RTC_CHECK(size_packets_ > 0 || queue_time_sum_ == TimeDelta::Zero());std::unique_ptr<RtpPacketToSend> rtp_packet(queued_packet.RtpPacket());stream->packet_queue.pop();// If there are packets left to be sent, schedule the stream again.RTC_CHECK(!IsSsrcScheduled(stream->ssrc));if (stream->packet_queue.empty()) {stream->priority_it = stream_priorities_.end();} else {int priority = stream->packet_queue.top().Priority();stream->priority_it = stream_priorities_.emplace(StreamPrioKey(priority, stream->size), stream->ssrc);}return rtp_packet;
}
  • 获得优先级最高的stream;

  • 从stream的packet_queue当中取出第一个包;

  • 将stream在stream_priorities_中的项删除;

    • 思考下虽然包删除了,但是stream还在,为啥要删除?

      答案:因为stream_priorities_ 是multimap,允许出现相同key,也就是说,这个包没有,它的stream优先级全靠它撑着(因为是先pop优先级高的包),所以,现在不应该由它撑着了,换下一个优先级最高的包撑着。

  • 计算Packet入队后距离现在的时间(不包括暂停时间);

  • 将这段时间从队列的总时间减去;

  • enqueue_times_中将Packet的项删除;

  • 总包数减去1;

  • 总字节数减去包的字节数;

  • 将包从stream中的queue中弹出;

  • 如果stream中的队列为空,则令stream的priority_it指向stream_priorities_end();

  • 否则,从stream队列头部取出Packet,将该Packet的priority插入到stream_priorities_中;

四、优先级调度:

  • 每个流有单独的优先级队列(PriorityPacketQueue),保存 QueuedPacket 对象。

  • QueuedPacket 是一个包装类,表示单个 RTP 数据包及其附属信息(例如入队时间、优先级、是否为重传包等)。

  • 列表中的流按 StreamPrioKey 保存在 stream_priorities_ 中,通过此键决定流次序:

    struct StreamPrioKey {int priority;    // 流的优先级,数值越低,优先级越高DataSize size;   // 数据包大小,用于平衡负载
    };
    

    优先规则:优先级低(priority 值小) > 数据包大小小(size 值小)。

五、轮询调度:

  • 核心逻辑通过 RoundRobin 的方式轮询多个流。但由于流可能有不同的优先级,某些流会被更多次轮询到。
  • 函数 GetHighestPriorityStream 定位当前最高优先级的流,从流对应的队列中取得包然后发送。

六、Stream定义与管理:

每个流由 Stream 类表示,Stream 是该流独有的数据结构,包括:

  • 当前队列状态,如总字节数、包大小和优先级。
  • 内部维护单独的优先级队列(PriorityPacketQueue)。
  • 调度时实时更新优先级,确保新加入高优先级包时能调整队列次序。

七、其他特性:

7.1、重传支持:

  • 标记是否重传的包,在出队时可能依据该标记进行特殊处理。

7.2、时间相关:

  • queue_time_sum_pause_time_sum_ 用于统计包在队列中的存留时间,这对于带宽控制和流量管理很有用。
  • 提供接口如 AverageQueueTime 计算平均队列时间,用于监控流的实时性。

7.3、队列字节限制:

队列有最大可存储的字节数(max_size_),以防止占用过多资源。

7.4、暂停/恢复功能:

可以通过 SetPauseState 暂停或者恢复队列处理。劝你最好别用!!!

八、总结:

RoundRobinPacketQueue 是一个高效的多流、多优先级调度队列,适用于 RTP 媒体数据的分组发送场景。它通过流内、流间的双重调度机制,结合优先级动态提升、统计队列时间和暂停控制等特性,确保在带宽有限的网络环境中最大程度提高数据的实时性和发送效率,是 WebRTC Pacer 模块的核心部分。

相关文章:

WebRTC服务质量(10)- Pacer机制(02) RoundRobinPacketQueue

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…...

VSCode调试

目录 C/C远程本地调试插件配置参考 C/C远程本地调试 测试源码&#xff1a;https://github.com/jrhee17/ssl-study 插件 Remote - SSH C/C 配置 .vscode/launch.json {"version": "0.2.0","configurations": [{"name": "afte…...

【ES6复习笔记】解构赋值(2)

介绍 解构赋值是一种非常方便的语法&#xff0c;可以让我们更简洁地从数组和对象中提取值&#xff0c;并且可以应用于很多实际开发场景中。 1. 数组的解构赋值 数组的解构赋值是按照一定模式从数组中提取值&#xff0c;然后对变量进行赋值。下面是一个例子&#xff1a; con…...

01 - 初识 Spring

初识Spring 企业级应用 企业级应用是指那些为商业组织、⼤型企业而创建并部署的解决⽅案及应用。这些⼤型的企业级应用结构复 杂、涉及的外部资源众多&#xff0c;事务密集&#xff0c;数据规模⼤&#xff0c;用户数量多&#xff0c;有较强的安全性考虑和较⾼的性能要求。 …...

重装荣耀X14笔记本电脑踩坑记

这几天趁着有国补搞了台荣耀 X14笔记本电脑。到手后第一件事情对我来说当然是要重装成Windows 11 LTSC版。所以按以往的经验做了个USB启动安装盘&#xff0c;但发现上电后按F12能进入启动设备选择&#xff0c;可是USB分类下没有任何设备。重启按F2进入设置界面&#xff0c;关闭…...

华为管理变革之道:奋斗文化与活力

目录 企业文化是什么&#xff1f; 为什么活下去是华为的文化&#xff1f; 活下来&#xff0c;是华为公司的最低纲领&#xff0c;也是华为公司的最高纲领&#xff01; 资源终会枯竭&#xff0c;唯有文化才能生生不息 企业文化之一&#xff1a;以客户为中心 企业文化之二&a…...

代码随想录算法训练营第十五天-二叉树-110.平衡二叉树

所谓平衡二叉树是指任意子树的高度差不超过1目前所学习的有关二叉树的问题&#xff0c;都是基于二叉树的遍历顺序来实现的 #include <iostream> #include <sstream> #define LEN 10009struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(): val(0…...

各种网站(学习资源、常用工具及其他,持续更新中~)

欢迎围观笔者的个人博客~ 也欢迎通过RSS网址https://kangaroogao.github.io/atom.xml进行订阅~ 大学指南 上海交通大学生存手册中国科学技术大学人工智能与数据科学学院本科进阶指南USTC不完全入学指南大学生活质量指北科研论 信息搜集 AI信息搜集USTC飞跃网站计算机保研 技…...

【gunicorn -k gevent 参数gevent说明,主要CPU密集和I/O密集型】

CPU 密集型和I/O 密集型是两种不同的计算任务类别&#xff0c;它们的性能瓶颈来源不同&#xff1a; 1. CPU 密集型 定义 CPU 密集型任务是指主要消耗 CPU 计算资源 的任务。这类任务需要大量的计算操作&#xff0c;而很少涉及 I/O 操作&#xff08;如网络或磁盘的读写&#x…...

快速理解24种设计模式

简单工厂模式 建立产品接口类&#xff0c;规定好要实现方法。 建立工厂类&#xff0c;根据传入的参数&#xff0c;实例化所需的类&#xff0c;实例化的类必须实现指定的产品类接口 创建型 单例模式Singleton 保证一个类只有一个实例&#xff0c;并提供一个访问他它的全局…...

5G -- 5G网络架构

5G组网场景 从4G到5G的网络演进&#xff1a; 1、UE -> 4G基站 -> 4G核心网 * 部署初中期&#xff0c;利用存量网络&#xff0c;引入5G基站&#xff0c;4G与5G基站并存 2、UE -> (4G基站、5G基站) -> 4G核心网 * 部署中后期&#xff0c;引入5G核心网&am…...

硬件开发笔记(三十二):TPS54331电源设计(五):原理图BOM表导出、元器件封装核对

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144753092 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

UE5 崩溃问题汇总!!!

Using bundled DotNet SDK version: 6.0.302 ERROR: UnrealBuildTool.dll not found in "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll" 在你遇到这种极奇崩溃的BUG &#xff0c;难以解决的时候。 尝试了N种方法&#xff0c;都不行的解决方法。…...

美国站群服务器如何帮助实现有效的多域名管理?

国站群服务器以其丰富的IP资源、高性能硬件和灵活的配置选项&#xff0c;成为多域名管理的理想选择。特别是在需要针对不同域名实现SEO优化、业务分离或多站点运营的场景中&#xff0c;美国站群服务器提供了高效且实用的解决方案。以下是如何利用美国站群服务器实现有效的多域名…...

VMware的三种网络模式——在NAT模式下开放接口为局域网内其他主机提供服务

众所周知 VMware 有三种常用的网络通讯模式&#xff0c;分别是&#xff1a;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09;&#xff0c;它们各有不同的用法。 Bridged 桥接模式是与主机…...

【漏洞复现】灵当CRM datapdf.php 任意文件读取漏洞

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…...

MySql详细教程-从入门到进阶(超实用)

基础篇 通用语法及分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用…...

【C语言练习(17)—输出杨辉三角形】

C语言练习&#xff08;17&#xff09; 文章目录 C语言练习&#xff08;17&#xff09;前言题目题目解析整体代码 前言 杨辉三角形的输出可以分三步&#xff0c;第一步构建一个三角形、第二步根据规律将三角形内容填写、第三步将三角形以等腰的形式输出 题目 请输出一个十行的…...

服务器压力测试怎么做

在部署任何Web应用程序或服务之前&#xff0c;进行服务器压力测试&#xff08;也称为负载测试&#xff09;是确保系统能够处理预期用户流量的关键步骤。通过模拟大量并发请求&#xff0c;可以评估服务器的性能、稳定性和响应时间&#xff0c;识别潜在瓶颈&#xff0c;并优化资源…...

深度学习中的正则化

深度学习中的正则化(regularization)旨在防止过拟合并提高模型对未知数据的泛化能力。正则化是一种通过在给定的训练集上适当地拟合函数并避免过度拟合来减少误差的技术。 通过对模型参数添加约束&#xff0c;正则化鼓励模型学习更简单、更稳健的模式&#xff0c;从而降低其对噪…...

深入了解 React:从入门到高级应用

深入了解 React&#xff1a;从入门到高级应用 React 是由 Facebook 开发并维护的一个开源 JavaScript 库&#xff0c;用于构建用户界面。自2013年发布以来&#xff0c;React 在前端开发领域迅速崛起&#xff0c;成为最受欢迎的 UI 构建工具之一。无论是小型的单页应用&#xf…...

华为云环境下LVS/DR架构的故障诊断优化

本文作者&#xff1a;刘涛 文章目录 前言1.LVS/DR集群的问题2.华为云环境3.问题排查3.1 检查LVS/DR模式配置3.1.1 RS服务器3.1.2 DS服务器 3.2 继续分析抓包结果3.2.1 调整tcpdump抓包过滤条件3.2.2 client向集群VIP发包3.2.3 DS服务器arp消息 3.3 查看丢包3.3.1 监控DS和RS服…...

Effective C++ 条款 22:将成员变量声明为 private

文章目录 条款 22&#xff1a;将成员变量声明为 private核心思想示例代码注意事项结论 条款 22&#xff1a;将成员变量声明为 private 核心思想 成员变量的封装性 将成员变量声明为 private 是面向对象设计的重要原则&#xff0c;有助于保持封装性。 为何使用 private&#x…...

ShardingSphere(分库分表)

ShardingSphere 高性能架构模式 读写分离架构&#xff1a; 基本原理是将数据库读写操作分散到不同的节点上&#xff0c;主库负责处理事务性的增删改操作&#xff0c;从库负责处理查询操作。避免由数据更新导致的行锁&#xff0c;来提升性能。 一主一从&#xff1a;可以将查…...

Visual Studio Code(VS Code)配置C/C++环境

一、Visual Studio Code安装 Visual Studio Code&#xff0c;下文中简称为VS Code的详细安装方法请参考VSCode安装教程&#xff08;超详细&#xff09;-CSDN博客 二、MinGW编译器下载与配置 1、MinGW介绍 MinGW(Minimalist GNU for Windows)是一款用于Windows 平台的轻…...

使用 OpenCV 在图像中添加文字

在图像处理任务中&#xff0c;我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数&#xff0c;可以很方便地在图像上绘制文本&#xff0c;支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字&#xff0c;介绍 cv2.putTe…...

高校网络安全_网络安全之道

需要对学校的网络进行安全防护&#xff0c;主要有这么几个痛点&#xff1a; 传统本地化产品难以及时更新情报库&#xff0c;应对新型攻击。 近年来&#xff0c;黑客和黑产团伙攻击手 段呈现多样化实战化&#xff0c;除传统僵木蠕外&#xff0c;各类新型、复杂甚至未知威胁高发…...

『大模型笔记』评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释

评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释 文章目录 一. ELO Rating大模型的elo得分如何理解1. Elo评分的基本原理2. 示例说明3. 大模型中的Elo得分总结3个模型之间如何比较计算,给出示例进行解释1. 基本原理扩展到三方2. 示例计算第一场: A A…...

kafka的配置

server.properties server.properties模板 # broker id&#xff0c;多个broker服务器的话&#xff0c;每个broker id必须不同 broker.id1# kafka broker所在节点的 hostnamehostname10.1.1.1.3:9092# 处理网络请求的线程数 num.network.threads 8# 执行磁盘IO的线程数 num.io…...

Linux下Java通过JNI调用C++

以下为Demo流程 1.创建Java文件 public class HelloWord {// 声明本地方法public native void sayHello();static {// 加载本地库System.loadLibrary("hello");}public static void main(String[] args) {new HelloWord().sayHello();} } 2.编译生成.h头文件 在H…...

家政预约小程序数据库设计

目录 1 如何设计表结构1.1 用户表1.2 服务分类表1.3 服务表1.4 服务规格表1.5 订单表1.6 服务人员表1.7 评价表1.8 促销活动表1.9 投诉表1.10 年卡表1.11 派单表1.12 支付记录表1.13 通知记录表1.14 优惠券表1.15 用户优惠券表1.16 消息模板表1.17 积分记录表 经过一系列的设计…...

【Git学习】windows系统下git init后没有看到生成的.git文件夹

[问题] git init 命令后看不到.git文件夹 [原因] 文件夹设置隐藏 [解决办法] Win11 win10...

云手机群控能用来做什么?

随着云手机的发展&#xff0c;云手机群控技术逐渐从小众的游戏多开工具&#xff0c;发展为涵盖多个领域的智能操作平台。不论是手游搬砖、短视频运营&#xff0c;还是账号养成等场景&#xff0c;云手机群控都展现出了强大的应用潜力。本文将为大家详细解析云手机群控的应用场景…...

go下载依赖提示连接失败

1、现象 Go下载模块提示连接失败 dial tcp 142.251.42.241:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.…...

在线excel编辑(luckysheet)

项目地址&#xff1a;Luckysheet: &#x1f680;Luckysheet &#xff0c;一款纯前端类似excel的在线表格&#xff0c;功能强大、配置简单、完全开源。 可以下载项目使用npm安装运行&#xff0c;也可以用cdn 加载excel文件&#xff08;使用luckyexcel&#xff09;&#xff1a; …...

2024国赛A题第一问

第一问 板凳龙等距螺线匀速运动模型的建立 坐标系的建立 根据题意&#xff0c;舞龙队沿螺距为55cm的螺线顺时针进入&#xff0c;进入位置为螺线第16圈点A处&#xff0c;即整个螺线的最外侧点&#xff0c;设定其为 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)。为了便于计算出题目要…...

【魅力golang】之-反射

1、引言 反射&#xff08;Reflection&#xff09;在 Golang中用于运行时检查和操作变量的类型和值。通过反射&#xff0c;可以实现动态类型处理&#xff0c;这在构建泛型代码、框架、序列化工具和动态代理等场景中非常有用。 2、什么是反射 反射是指程序在运行时能够动态地检…...

Java在 聊天管理系统中的应用

聊天管理系统已经成为人们日常沟通不可或缺的一部分。无论是企业内部的即时通讯&#xff0c;还是社交媒体平台的聊天功能&#xff0c;聊天管理系统都扮演着至关重要的角色。 Java 作为一种广泛应用的编程语言&#xff0c;凭借其强大的功能、良好的跨平台性以及丰富的类库&…...

记一次rac故障原因分析(虚拟化平台)

一 现象描述 XX客户于1月14号凌晨业务中断&#xff0c;检查数据库发现数据库集群宕机。 XX客户于2月14号春节初五早上业务异常&#xff0c;连接数据库无响应。 二 问题详细诊断 1月14号故障 1月14号凌晨2点&#xff0c;客户反馈业务中断&#xff0c;发现节点1无法连接&…...

opencv中的各种滤波器简介

在 OpenCV 中&#xff0c;滤波器是图像处理中的重要工具&#xff0c;用于对图像进行平滑、去噪、边缘检测等操作。以下是几种常见滤波器的简单介绍。 1. 均值滤波 (Mean Filter) 功能&#xff1a; 对图像进行平滑处理&#xff0c;减少噪声。 应用场景&#xff1a; 去除图像…...

文本数据处理

文本数据处理 一、数据转换与错误处理 &#xff08;一&#xff09;运维中的数据转换问题 在计算机审计及各类数据处理场景中&#xff0c;数据转换是关键步骤&#xff0c;涉及将被审计单位或其他来源的数据有效装载到目标数据库&#xff0c;并明确标示各表及字段含义与关系。…...

ThinkPHP 8开发环境安装

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《ThinkPHP 8高效构建Web应用 夏磊 编程与应用开发丛书 清华大学出版社》【摘要 书评 试读】- 京东图书 1. 安装PHP8 Windows系统用户可以前往https://windows.php.net/downloads/releases/archives/下载PHP 8.0版本&am…...

php怎么去除数点后面的0

在PHP中&#xff0c;我们可以使用几种方法来去除数字小数点后的0。 方法一&#xff1a;使用intval函数 intval函数可以将一个数字转化为整数&#xff0c;另外&#xff0c;它也可以去除小数点后面的0。 “php $number 123.4500; $number intval($number); echo $number; // 输…...

Database.NET——一款轻量级多数据库客户端工具

文章目录 Database.NET简介下载使用使用场景总结 Database.NET简介 Database.NET 是一个功能强大且易于使用的数据库管理工具&#xff0c;适用于多种数据库系统。它为开发者和数据库管理员提供了一个统一的界面&#xff0c;可以方便地管理和操作不同类型的数据库。 支持的数据…...

Unittest02|TestSuite、TestRunner、HTMLTestRunner、处理excel表数据、邮件接收测试结果

目录 八、测试套件TestSuite和测试运行器TestRunner 1、基本概念 2、创建和使用测试套件 3、 自动发现测试用例、创建测试套件、运行测试 4、生成html的测试报告&#xff1a;HTMLTestRunner 1️⃣导入HTMLTestRunner模块 2️⃣运行测试用例并生成html文件 九、unittest…...

protobuf学习使用

1、概述 protobuf是Google开发的一种语言中立、平台无关、可扩展的序列化结构数据格式。允许定义一次数据结构&#xff0c;然后可以使用各种支持的语言来生成代码&#xff0c;以轻松地读写这些结构到一个二进制流中&#xff0c;如网络传输或文件&#xff0c;Protobuf支持多种编…...

跟我学c++中级篇——C++中的缓存利用

一、缓存 学习过计算机知识的一般都知道缓存这个概念&#xff0c;大约也知道缓存是什么。但是如果是程序员&#xff0c;如何更好的利用缓存&#xff0c;可能就有很多人不太清楚了。其实缓存的目的非常简单&#xff0c;就是了更高效的操作数据。大家都听说过“局部性原理”&…...

Goland 安装与使用

GoLand安装 官方网址&#xff1a; JetBrains GoLand&#xff1a;不只是 Go IDE 1. 进入官网&#xff0c;点击下载&#xff1a; ​ 2. 如下图一步步安装 ​ ​ ​ ​ ​ 3. 如下图一步步安装...

cesium通过经纬度获取3dtiles 得feature信息

找到这里3dtiles的两种访问方式&#xff1a; 1.1 3DTileContent#getFeature 这里涉及3DTile 数据结构&#xff0c;暂不了解3DTile 数据结构&#xff0c;因此暂不使用。 1.2 scene.pick 本次使用 scene表示虚拟场景中所有 3D 图形对象和状态的容器&#xff1b;scene中…...

spring cloud gateway 3

**Spring Cloud Gateway 3** 是 Spring Cloud 生态系统中的一个重要组件&#xff0c;用于构建 API 网关&#xff0c;提供路由、监控、安全等关键功能。以下是关于 Spring Cloud Gateway 3 的详细介绍&#xff1a; ## 1. 什么是 Spring Cloud Gateway&#xff1f; **Spring Clou…...