Sentinel规则持久化pull模式核心源码解析
文章目录
- 前言
- 一、服务端新增/修改规则
- 1.1、repository.save
- 1.2、publishRules
- 二、客户端接收规则
- 三、持久化扩展
- 3.1、持久化原理
- 3.1.1、FileRefreshableDataSource
- 3.1.1.1、super关键字
- 3.1.1.2、firstLoad()方法
- 3.1.2、FlowRuleManager.register2Property
- 3.2、持久化实现
- 总结:Sentinel 规则持久化:Pull 模式下的客户端与服务端处理流程
前言
在Sentinel的控制台(服务端)设置了流控、系统等规则后,点击保存按钮,会调用服务端FlowControllerV1
的接口。Sentinel默认会将规则在服务端的内存中保存一份,然后推送到客户端,默认情况下也是推送到客户端的内存中。因为是保存在内存中,所以应用重启后,上一次配置的规则就会消失,需要重新进行配置。
如果希望在客户端持久化一份,可以在服务端将规则推送到客户端后,自己实现扩展,或引入官方的jar包:
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-datasource-extension -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-extension</artifactId><version>1.8.0</version>
</dependency>
将规则更新到本地文件或数据库中。同时监控线程定期读取本地文件或数据库中的配置信息,如果发生变化,就会更新最新的逻辑到内存中:
图片来源:图灵学院
一、服务端新增/修改规则
当在服务端的控制台页面上新增流控规则时,实际会调用/v1/flow/rule
对应的方法:
该方法在FlowControllerV1
:
参数FlowRuleEntity
,也就是流控规则窗口中的选项:
最关键的是下图中的两个方法(修改规则同理,是 @PutMapping(“/save.json”) 的请求方式,最终同样会调用下图中的两个方法)
1.1、repository.save
该方法的作用,是将控制台页面上设置的规则,保存一份到服务端
的内存中:
在调用save
方法的InMemoryRuleRepositoryAdapter
类中,有三个属性:
- machineRules:保存每台机器对应的规则。
MachineInfo
表示一个具体的 Sentinel 客户端:
MachineInfo(ip=192.168.1.10, port=8719) → {
1001L → FlowRule(…),
1002L → FlowRule(…)
}
- allRules:保存所有机器对应的规则。
1001L → FlowRule(…),
1002L → DegradeRule(…),
1003L → ParamFlowRule(…)
- appRules:保存每个应用对应的规则集合
“order-service” → {
1001L → FlowRule(…),
1002L → DegradeRule(…)
}
“payment-service” → {
2001L → FlowRule(…)
}
1.2、publishRules
该方法是将服务端的规则信息推送一份到客户端,首先会获取当前机器下配置的所有规则,然后调用setFlowRuleOfMachineAsync
:
会再加一个参数,标记当前规则的类型
在该方法中发起post请求,进行推送规则,在推送规则前,还会通过toRule
方法,将参数转换为各自规则的客户端接收参数类型(例:流控规则,服务端的参数是FlowRuleEntity
,而客户端接收的参数类型是FlowRule
,所以需要转换一下)
二、客户端接收规则
Sentinel 控制台和客户端之间通过 Socket(基于 TCP)通信。当客户端启动时,会启动一个SimpleHttpCommandCenter
(服务端也有),监听一个端口( 8719),并注册各种命令处理器。
- 启动时扫描所有标注了 @CommandMapping 的类;
- 将这些处理类注册到一个 Map<String, CommandHandler> 中,键是 name(比如 “setRules”);
- 当 Socket 接收到客户端发来的请求命令:
- 解析请求命令名(如 /setRules?type=flow&data=[…]);
- 根据命令名找到对应的 handler;
- 调用该类的 handle() 方法来处理这次命令请求;
- 返回处理结果作为 socket 响应。
最终调用的是ModifyRulesCommandHandler
的handle
方法:
在该方法中,会进行请求类型的判断,进入不同的分支。例如流控,先还原出请求的实体类型,然后通过各自manager
管理器的loadRules
方法,将规则保存一份到**客户端(微服务)**的内存中:
flowRules
就是规则在服务端内存的体现:
- key:资源名,即需要被限流的业务资源,比如接口名、方法名、URL 等。
- value:针对该资源的所有流控规则的列表。
将各自的规则存入内存中后,客户端在进行对应的规则校验时,就会进行读取,例如限流:
获取该资源设置的所有流控规则
这里的flowRules就是在接收到服务端setRules请求后设置的
在这一行代码中,会去尝试将规则持久化到文件或DB,Redis等中间件中
:
如果没有自定义实现,或者引入第三方的jar包,这里的WritableDataSource
是空的。也就是不会走持久化的逻辑。
没有持久化,返回给服务端的信息中会进行标识:
三、持久化扩展
3.1、持久化原理
官方对于客户端的持久化,有一个案例,在Sentinel的sentinel-demo
模块下的sentinel-demo-dynamic-file-rule
中:
可以运行一下这个demo:
public class FileDataSourceDemo {public static void main(String[] args) throws Exception {FileDataSourceDemo demo = new FileDataSourceDemo();demo.listenRules();/** Start to require tokens, rate will be limited by rule in FlowRule.json*/FlowQpsRunner runner = new FlowQpsRunner();runner.simulateTraffic();runner.tick();}private void listenRules() throws Exception {ClassLoader classLoader = getClass().getClassLoader();String flowRulePath = URLDecoder.decode(classLoader.getResource("FlowRule.json").getFile(), "UTF-8");
// String degradeRulePath = URLDecoder.decode(classLoader.getResource("DegradeRule.json").getFile(), "UTF-8");
// String systemRulePath = URLDecoder.decode(classLoader.getResource("SystemRule.json").getFile(), "UTF-8");// Data source for FlowRuleFileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(flowRulePath, flowRuleListParser);FlowRuleManager.register2Property(flowRuleDataSource.getProperty());// Data source for DegradeRule
// FileRefreshableDataSource<List<DegradeRule>> degradeRuleDataSource
// = new FileRefreshableDataSource<>(
// degradeRulePath, degradeRuleListParser);
// DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
//
// // Data source for SystemRule
// FileRefreshableDataSource<List<SystemRule>> systemRuleDataSource
// = new FileRefreshableDataSource<>(
// systemRulePath, systemRuleListParser);
// SystemRuleManager.register2Property(systemRuleDataSource.getProperty());}private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<FlowRule>>() {});private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<DegradeRule>>() {});private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<SystemRule>>() {});
}
输出的效果:
83 send qps is: 39
1744526839080, total:39, pass:20, block:19
82 send qps is: 37
1744526840080, total:37, pass:17, block:20
81 send qps is: 34
1744526841081, total:34, pass:21, block:13
因为在FlowRule.json
文件中是这样配置的:
运行时修改target目录下该文件的值:
发现放行的请求数量也随之发生改变。
1744526970761, total:38, pass:20, block:18
93 send qps is: 41
1744526971761, total:41, pass:20, block:21
92 send qps is: 37
1744526972761, total:37, pass:25, block:12
91 send qps is: 37
1744526973762, total:37, pass:37, block:0
90 send qps is: 41
1744526974762, total:41, pass:40, block:1
89 send qps is: 42
1744526975770, total:42, pass:42, block:0
88 send qps is: 46
1744526976771, total:46, pass:39, block:7
87 send qps is: 42
1744526977771, total:42, pass:38, block:4
这个Demo实际就是模拟了将规则持久化到本地文件,并且动态感知文件变化,刷新规则的操作。
那么是如何实现上面的效果的?关键代码在于FileRefreshableDataSource
和FlowRuleManager.register2Property
:
3.1.1、FileRefreshableDataSource
在实例化FileRefreshableDataSource
时,实际会调用到下面的构造。其中关键代码在于super
关键字的调用以及firstLoad()
方法:
3.1.1.1、super关键字
super
关键字会调用其父类AutoRefreshDataSource
的构造。
在startTimerService()
方法中,会利用线程池启动一个定时任务,默认是3s执行一次:
该定时任务主要完成的逻辑:
- 判断客户端持久化的规则文件是否被修改,
- 如果被修改,就重新去读取,并且利用对应监听器的
configUpdate
方法,将持久化的规则文件中的最新值,刷回到客户端内存的FlowRuleManager
的flowRules
中。
3.1.1.2、firstLoad()方法
firstLoad
则是在第一次启动时,读取持久化到本地的配置规则的值,并且刷回到客户端内存的FlowRuleManager
的flowRules
中。
所以完成图上第6步的关键,就在于FileRefreshableDataSource
3.1.2、FlowRuleManager.register2Property
该方法的参数,就是上一步得到的规则实例:
主要用于给新传进来的 property (上一步得到的规则实例)添加监听器,监听规则变化:
上面的Demo,只演示了当持久化的规则文件发生变化时,通过定时任务监控变化,并且修改内存中的值的操作,还缺少客户端接收服务端的推送,然后进行持久化的操作。也就是ModifyRulesCommandHandler
的handle
方法的:
3.2、持久化实现
对于持久化的实现,也有一个案例,只不过最终多了一个客户端接收服务端的推送,然后进行持久化的操作。
public class FileDataSourceInit implements InitFunc {@Overridepublic void init() throws Exception {// A fake path.String flowRuleDir = System.getProperty("user.home") + File.separator + "sentinel" + File.separator + "rules";String flowRuleFile = "flowRule.json";String flowRulePath = flowRuleDir + File.separator + flowRuleFile;ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));// Register to flow rule manager.FlowRuleManager.register2Property(ds.getProperty());WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);// Register to writable data source registry so that rules can be updated to file// when there are rules pushed from the Sentinel Dashboard.WritableDataSourceRegistry.registerFlowDataSource(wds);}private <T> String encodeJson(T t) {return JSON.toJSONString(t);}
}
上面的案例,可以直接拿来使用。因为实现了InitFunc
接口,只需要进行SPI的配置,具体是在工程的resource下加入:
文件的内容是实现了InitFunc
的包名 + 类名。
这样在调用被保护的资源时,会进入Env的静态代码块:
通过SPI机制加载文件,并且执行其中的init方法:
这里就有我们刚刚自定义的:
执行自定义的init,会向WritableDataSourceRegistry
中注册一个数据源:
List<InitFunc> initFuncs = SpiLoader.of(InitFunc.class).loadInstanceListSorted();
这一行代码中,解析出的init实现类,还有一个CommandCenterInitFunc
也非常的关键,优先级也是最高的,在它的内部,会启动线程,去监听控制台开放的端口,并且还有初始化所有CommandHanlder,以及调用转发的逻辑。
总结:Sentinel 规则持久化:Pull 模式下的客户端与服务端处理流程
在 Sentinel 的规则持久化 Pull 模式 中,客户端与服务端(控制台)分别承担不同的职责与处理逻辑。该模式下,控制台主动推送规则,客户端被动接收并进行持久化。
服务端(控制台)处理逻辑
当在控制台执行新增、修改或删除规则操作时,请求将进入 FlowControllerV1
,其内部处理流程包括以下两个步骤:
- 规则同步到内存:
将页面上传递的规则进行新增、修改或删除,并同步更新服务端内存中的规则缓存。 - 规则推送至客户端:
通过 Socket 通信,将最新的规则数据推送至对应的客户端实例。
客户端处理逻辑
客户端在接收到服务端推送的规则后,会由 ModifyRulesCommandHandler
的 handle
方法负责处理,具体包括:
- 规则写入客户端内存:
解析服务端下发的规则,并更新客户端本地内存中的规则集合。 - 规则持久化(可选):
若客户端实现了自定义持久化逻辑(通过 SPI 机制,提供InitFunc
接口的实现类),则会按照配置的持久化策略,将规则保存到本地文件、数据库或其他存储介质中。
客户端规则持久化关键点
- 服务端推送后的规则持久化
- 实现方式:调用
WritableDataSourceRegistry.registerFlowDataSource(...)
方法; - 作用:将规则注册为可写数据源,便于在接收到规则更新后,触发持久化操作。
- 本地规则文件变更的自动感知
- 实现方式:使用
FileRefreshableDataSource
组件; - 作用:支持客户端实时监听本地规则文件的变化,一旦检测到更新,即可自动加载并刷新内存中的规则数据,保持运行时规则与文件内容同步。
如需支持其他数据源(如 Nacos、Zookeeper、Apollo 等),可基于 Sentinel 提供的 SPI 接口扩展 ReadableDataSource
和 WritableDataSource
,实现自定义的数据加载与保存逻辑。
如果想要在Spring Boot启动时,就直接完成init逻辑,可以自定义实现ApplicationRunner
或CommandLineRunner
接口。通过SPI机制的init实现,实际上是懒加载的,在调用目标资源方法时才会执行。
相关文章:
Sentinel规则持久化pull模式核心源码解析
文章目录 前言一、服务端新增/修改规则1.1、repository.save1.2、publishRules 二、客户端接收规则三、持久化扩展3.1、持久化原理3.1.1、FileRefreshableDataSource3.1.1.1、super关键字3.1.1.2、firstLoad()方法 3.1.2、FlowRuleManager.register2Property 3.2、持久化实现 总…...
【go】--编译
go build -o [编译完成的可执行文件] [需要编译的.go文件]#例如 go build -o myapp main.go#确保编译的结果和当前运行环境相同 #查看arch uname -a在 Linux 中查看和修改 GOOS 和 GOARCH 环境变量: 1. 查看当前 Go 环境变量 # 查看所有Go相关的环境变量 go env# …...
【Spring底层分析】Spring IoC
Spring IoC IoC:控制反转。将对象创建和对象之间的调用交给Spring容器来管理。好处是降低了对象之间的耦合度。 DI:依赖注入。给bean对象注入依赖的对象。 大白话就是:Spring帮你创建对象,对象的属性如果依赖于某个对象…...
Ubuntu系统进程管理
在Ubuntu系统中,进程管理是系统维护和性能调优的重要部分。以下是关键命令和技巧的总结,帮助你有效管理系统进程: 1. 查看进程 ps 命令:查看当前进程快照。 bash ps aux # 查看所有运行中的进程(a所有用户…...
HDU2196 Computer 树形DP
原题链接 既然要查找每个节点的最远到达距离,由于该图是个树,我们就找从根节点向下遍历方向的终点的距离与先返回父节点再从最优的父节点沿着原来的方向的终点的距离的最大值 如图所示 也就是说,我们需要获得当前点的正距离最大值和正距离最…...
【第四十周】文献阅读:用于检索-增强大语言模型的查询与重写
目录 摘要Abstract用于检索-增强大语言模型的查询与重写研究背景方法论基于冻结LLM的重写方案基于可训练重写器的方案重写器预热训练(Rewriter Warm-up)强化学习(Reinforcement Learning) 创新性实验结果局限性总结 摘要 这篇论文…...
Istio常用命令
Istio常用命令 1. 安装和配置2. Sidecar 注入3. 验证和状态4. 升级和卸载5. 故障排除6. 配置管理 istioctl 的常用命令及其详细说明: 1. 安装和配置 安装 Istio # 使用指定的配置文件(如 demo)安装 Istio 到 Kubernetes 集群。 istioctl m…...
Linux基础15
一、网络模型 二、eNSP模拟器 拖拽操作建立模拟网络环境 交换机视图操作: <> 用户视图 [] 系统视图 接口视图 协议视图 display version #显示版本和设备型号 display current-configuration #查看设备配置(查错) …...
FISCO BCOS群组扩容实战指南:从原理到操作全解析
引言:为什么需要群组扩容? 在区块链技术迅猛发展的今天,企业级应用对区块链平台提出了更高的要求。"如何在不影响现有业务的情况下扩展区块链处理能力?"、"能否实现不同业务数据的物理隔离?"、&qu…...
【pytorch图像视觉】lesson17深度视觉应用(上)构建自己的深度视觉项目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、 数据1、认识经典数据1.1入门数据:MNIST、其他数字与字母识别(1)数据加载(2)查看数据的特征和标…...
从“被动跳闸”到“主动预警”:智慧用电系统守护老旧小区安全
安科瑞顾强 近年来,老旧小区电气火灾事故频发,成为威胁居民生命财产安全的重要隐患。据统计,我国居住场所火灾伤亡人数远超其他场所,仅今年一季度就发生8.3万起住宅火灾,造成503人遇难。这些建筑多建于上世纪&#x…...
2.1 全栈运维管理:Proxmox VE单节点配置桥接、VLAN和Bonding的详细实验指南
本文是Proxmox VE 全栈管理体系的系列文章之一,如果对 Proxmox VE 全栈管理感兴趣,可以关注“Proxmox VE 全栈管理”专栏,后续文章将围绕该体系,从多个维度深入展开。 概要:本文介绍 Proxmox VE 单节点网络配置。桥接基…...
docker面试题
1.docker网络 Docker网络是Docker容器之间进行通信的关键功能。Docker提供了多种网络模式和驱动,以满足不同的网络需求。以下是Docker网络的详细介绍: 1.Docker网络模式 Docker提供了以下几种网络模式,每种模式适用于不同的场景:…...
计算机视觉——基于YOLOV8 的人体姿态估计训练与推理
概述 自 Ultralytics 发布 YOLOV5 之后,YOLO 的应用方向和使用方式变得更加多样化且简单易用。从图像分类、目标检测、图像分割、目标跟踪到关键点检测,YOLO 几乎涵盖了计算机视觉的各个领域,似乎已经成为计算机视觉领域的“万能工具”。 Y…...
【本地图床搭建】宝塔+Docker+MinIO+PicGo+cpolar:打造本地化“黑科技”图床方案
写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言宝塔安装DockerMinIO 安装与设置cploar内网穿透PicGo下载与安装typora安装总结互动…...
【家政平台开发(41)】家政平台性能蜕变:性能测试与优化全解析
本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…...
监控docker中的java应用
1)进入指定的容器 docker exec -it demo /bin/bash 2)下载curl root89a67e345354:/# apt install curl -y 3)下载arthas root89a67e345354:/# curl -O https://arthas.aliyun.com/arthas-boot.jar 4)运行 root89a67e345354:/# java -jar arthas-boot.jar 5)监控 […...
Android游戏辅助工具开发详解
文章目录 第一部分:概述与基础准备1.1 游戏辅助工具的定义与用途1.2 开发环境准备1.3 项目创建与配置 第二部分:核心功能实现2.1 屏幕点击功能实现2.1.1 基础点击功能2.1.2 多点触控实现 2.2 滑动功能实现2.2.1 基础滑动功能2.2.2 曲线滑动实现 2.3 屏幕…...
重生之外卖配送时被投诉后的反思
重生之外卖配送时被投诉后的反思 写苍穹外卖时 我们发现在每一次调用sql语句时 insert update语句总会需要在service的实现类里加入例如create_time,create_user , update_time , update_user的填充 每次赋值都要重新编写代码,会造成代码冗余 ; 序号字…...
计算机基础复习资料整理
计算机基础复习资料整理 一、操作系统 (一)定义 操作系统(Operating System,OS)是介于计算机硬件和用户(程序或人)之间的接口。作为通用管理程序,它管理计算机系统中每个部件的活动…...
Profibus DP主站网关数据映射全解析!
Profibus DP主站网关数据映射全解析! 在工业自动化领域,Profibus DP主站网关作为一种关键的通讯设备,其数据映射的精准度和效率对整个控制系统的性能有着至关重要的影响。本文旨在深入探讨Profibus DP主站网关的数据映射过程,揭示…...
ocr-不动产权识别
目录 一、在阿里云申请ocr识别服务 二、创建springboot项目 三、后续 一、在阿里云申请ocr识别服务 在线体验:房产证图片上传 [阿里官方]不动产权证OCR文字识别_API专区_云市场-阿里云 (aliyun.com) 可以选择一毛500次这个 当然也可以白嫖100 下面有个在线调试…...
leetcode 198. House Robber
本题是动态规划问题。 第一步,明确并理解dp数组以及下标的含义 dp[i]表示从第0号房间一直到第i号房间(包含第i号房间)可以偷到的最大金额,具体怎么偷这里不考虑,第i1号及之后的房间也不考虑。换句话说,dp[i]也就是只考虑[0,i]号…...
【2025软考高级架构师】——软件架构设计(4)
摘要 本文主要介绍了几种软件架构设计相关的概念和方法。包括C2架构风格的规则,模型驱动架构(MDA)的起源、目标、核心模型及各模型之间的关系;软件架构复用的概念、历史发展、维度、类型及相关过程;特定领域架构&…...
分发饼干问题——用贪心算法解决
目录 一:问题描述 二:解决思路 贪心策略(C语言)算法复习总结3——贪心算法-CSDN博客 三:代码实现 四:复杂度分析 一:问题描述 分发饼干问题是一个经典的可以使用贪心算法解决的问题…...
深入详解MYSQL的MVCC机制
参考资料: 参考视频(注意第二个视频关于幻读的讲解是错误的,详情见本文) redoLog的结构详解 参考资料 学习内容: 1. MVCC要解决的问题 MVCC要解决的问题是,在不产生脏读等数据库问题的前提下,数据库的查询语句和更改语句不相互阻塞的情况; 在InnoDB中,MVCC仅仅存…...
DNS域名解析
目录 一.DNS 1.1DNS的简介 1.2DNS的背景 1.3DNS的架构 1.4实现DNS的方式 1.5DNS的查询类型 1.6DNS解析的基本流程 二.主从复制 2.1定义 2.2优缺点 三.DNS服务软件 3.1bind 3.1.1定义 3.1.2bind相关文件 3.2DNS服务器的核心文件 3.2.1主配置文件 3.2.2域名文件 …...
Java基础:一文讲清多线程和线程池和线程同步
01-概述 02-线程创建 继承Thread 实现Runnable(任务对象) 实现Callable接口 public class ThreadDemo3 {public static void main(String[] args) throws ExecutionException, InterruptedException {// 目标:线程创建3// 需求:求1-100的和Callable<…...
ubuntu 20.04 连不上蓝牙耳机/蓝牙鼠标
sudo gedit /etc/bluetooth/main.conf改为 ControllerMode dual然后重启蓝牙服务 sudo service bluetooth restart...
SaaS、Paas、IaaS、MaaS、BaaS五大云计算服务模式
科普版:通俗理解五大云计算服务模式 1. SaaS(软件即服务) 一句话解释:像“租用公寓”,直接使用现成的软件,无需操心维护。 案例:使用钉钉办公、在网页版WPS编辑文档。服务提供商负责软件更新和…...
【深拷贝、浅拷贝】golang函数参数传递,变量复制后,操作变量参数,是否影响原有数据?全面解析
Golang中深拷贝与浅拷贝的详细解析,以及变量复制、函数参数传递等场景下对新旧变量影响的总结: 一拷贝与浅拷贝的核心区别 1. 浅拷贝(Shallow Copy) • 定义:仅复制数据的顶层结构,对引用类型字段&#x…...
c语言编程经典习题详解3
21. 求给定正整数 n 以内的素数之积 定义:找出小于给定正整数n的所有素数,并将它们相乘。要点:使用双层for循环,外层循环遍历小于n的数,内层循环判断是否为素数,若是则累乘。应用:在数论研究、密码学等领域有应用。c #include <stdio.h>int isPrime(int num) {if…...
【HD-RK3576-PI】Docker搭建与使用
硬件:HD-RK3576-PI 软件:Linux6.1Ubuntu22.04 1. 安装Docker Docker安装脚本下载: roothd-rk3576-pi:~ $ curl -fsSL https://test.docker.com -o test-docker.sh 可以直接执行安装 roothd-rk3576-pi:~ $ sh test-docker.sh 2. 配置国内镜…...
C++进阶——异常
目录 1、异常的概念及使用 1.1 异常的概念 1.2 异常的抛出和捕获 1.3 栈展开 1.4 查找匹配的处理代码 1.5 异常的重新抛出 1.6 异常的安全问题 1.7 异常的规范 2、标准库的异常(了解) 1、异常的概念及使用 1.1 异常的概念 C语言,出错了,就报错…...
Linux安装开源版MQTT Broker——EMQX服务器环境从零到一的详细搭建教程
零、EMQX各个版本的区别 EMQX各个版本的功能对比详情https://docs.emqx.com/zh/emqx/latest/getting-started/feature-comparison.html...
C++ 编程指南36 - 使用Pimpl模式实现稳定的ABI接口
一:概述 C 的类布局(尤其是私有成员变量)直接影响它的 ABI(应用二进制接口)。如果你在类中添加或修改了私有成员,即使接口不变,编译器生成的二进制布局也会变,从而导致 ABI 不兼容。…...
笔记本电脑突然无法开机电源灯亮但是屏幕无法点亮
现象 按电源键,电源灯点亮,屏幕没动静 风扇开始运转,然后一会儿就不转了;屏幕一直没动静,屏幕没有任何反应(没有系统启动画面,没有徽标显示,就一点反应也没用) 这个问…...
mongodb 4.0+多文档事务的实现原理
1. 副本集事务实现(4.0) 非严格依赖二阶段提交 MongoDB 4.0 在副本集环境中通过 全局逻辑时钟(Logical Clock) 和 快照隔离(Snapshot Isolation) 实现多文档事务,事务提交时通过…...
decompiled.class file bytecode version50(java 6)
idea运行项目报错,跳到具体的.class中,idea会给出提示下载源码,点击下载报错,具体报错信息我没记录了(反正就是无法看到源码) 解决方式: 1、网上说下载scala插件,重启idea即可 但是…...
CSS 列表样式学习笔记
CSS 列表样式提供了强大的功能,用于定制 HTML 列表的外观。通过 CSS,可以轻松地改变列表项的标记类型、位置,甚至使用图像作为列表项标记。以下是对 CSS 列表样式的详细学习笔记。 一、HTML 列表类型 在 HTML 中,主要有两种类型…...
linux网络设置
ifconfig 查看ip地址 查看当前的liunx系统的网络参数ip地址 Ubuntu需要安装 Apt install -y net-tools 查看网络信息 Ifconfig 只能看到开启的网卡 Ifconfig -a 看到所有的网卡包括开启和关闭的 Ifconfig 网卡名称 up 开启网卡 Ifconfig 网卡名称 down 关闭网卡 If…...
抗干扰CAN总线通信技术在分布式电力系统中的应用
摘要:随着分布式电力系统的广泛应用,其通信系统的可靠性与稳定性受到了前所未有的挑战。CAN总线通信技术以其卓越的抗干扰性能和可靠性,在众多通信技术中脱颖而出,成为解决分布式电力系统通信问题的关键。本文深入剖析了CAN总线通…...
Maven工具学习使用(十二)——extension和depency的区别
在 Maven 中,extensions 和 dependencies 是两个不同的概念,它们在项目构建和依赖管理中扮演着不同的角色。 1、Dependencies dependencies 是 Maven 项目中用于管理项目所需的库和模块的部分。这些依赖可以是本地仓库中的,也可以是远程仓库…...
Python学生信息查询
利用字典设置学生信息,将这些信息放入列表中进行存储,根据输入的姓名查询展示对应的学生信息。 Student1{no:202001,name:zyt,score:87} Student2Student1.copy() Student3Student2.copy()Student2[no]202002 Student3[no]202003Student2[name]zwh Stud…...
一天时间,我用AI(deepseek)做了一个配色网站
前言 最近在开发颜色搭配主题的相关H5和小程序,想到需要补充一个web网站,因此有了这篇文章。 一、确定需求 向AI要答案之前,一定要清楚自己想要做什么。如果你没有100%了解自己的需求,可以先让AI帮你理清逻辑和思路,…...
MQ(消息队列)体系详解
消息队列(MQ,Message Queue) 是一种基于消息传递的异步通信机制,用于不同系统、服务之间进行数据传递和交互。它通常用来解耦生产者和消费者,提供高可用、高吞吐量和可靠的消息传递。 一、消息队列用途 1.系统解耦 …...
【GESP真题解析】第 3 集 GESP一级样题卷编程题 2:闰年求和
大家好,我是莫小特。 这篇文章给大家分享 GESP 一级样题卷编程题第 2 题:闰年求和。 题目链接 洛谷链接:B3846 闰年求和 一、完成输入 根据题目要求,我们需要输入两个整数,分别表示起始年份和终止年份。 要求计算…...
Windows Server 2019 安装 Docker 完整指南
博主本人使用的是离线安装 1. 安装前准备 系统要求 操作系统:Windows Server 2019(或 2016/2022)权限:管理员权限的 PowerShell网络:可访问互联网(或离线安装包) 启用容器功能 Install-Win…...
JetBrains PhpStorm v2024.3.1 Mac PHP开发工具
JetBrains PhpStorm v2024.3.1 Mac PHP开发工具 一、介绍 JetBrains PhpStorm 2024 mac,是一款PHP开发工具,直接开始编码,无需安装和配置大量插件。PhpStorm 从一开始就已包含 PHP、JavaScript 和 TypeScript 开发所需的一切,还…...
机器学习(ML)在AI驱动测试通过数据驱动的智能决策显著提升测试效率、覆盖率和准确性。
机器学习(ML)在AI驱动测试中扮演着 核心引擎 的角色,通过数据驱动的智能决策显著提升测试效率、覆盖率和准确性。以下是机器学习在测试各环节的具体作用及实现方案: 一、机器学习在测试生命周期中的作用 #mermaid-svg-u4vgPE6O2jugiZFB {font-family:"trebuchet ms&qu…...