高效利用资源:分布式有状态服务的高可靠性设计
在分布式系统设计中,实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时,备服务接管任务,例如通过Keepalive实现VIP的切换以保证可用性。然而,这种方式存在资源浪费的问题,因为备服务始终处于空转状态,未能充分利用系统资源。
程序的本质与分解
程序本质上由函数、对象(在面向对象语言中)和数据组合而成,通过特定的逻辑完成特定的业务目标。为了提升有状态服务的高可靠性和高可用性,我们可以从数据、函数和对象三个方面对程序进行分解:
- 数据持久化:在主备切换时,确保程序中的数据不丢失。通过数据持久化,可以在备服务接管后,基于持久化的数据重新运算,恢复服务状态。
- 纯函数设计:如果函数在相同条件下对相同输入总是产生相同输出,并且只完成其固有功能,具备单一职责,这类函数被称为纯函数。设计成纯函数后,可以基于持久化的数据进行重新计算,增强系统的可恢复性。
- 无状态对象:对象由数据和方法组成。如果对象的方法输出仅依赖于自身的状态,而不依赖外部状态,则该对象为无状态对象。无状态对象可以通过数据持久化进行重建,提升系统的灵活性和可扩展性。
横向扩展有状态服务的方法
为了实现有状态服务的横向扩展,并充分利用所有硬件资源,我们需要针对不同情况采用不同的方案。本文以Redis作为数据持久化方案为例,阐述如何实现有状态服务的横向扩展。
- 有状态对象:通过分布式锁确保同一时间仅有一个实例运行,保证控制逻辑的一致性。
- 纯函数/无状态对象:通过分布式任务调度器将任务分发到多个节点并行运行。
1. 管理有状态对象
如果程序中的对象为有状态对象,即对象的行为不仅依赖自身状态,还依赖外部状态。为了保证状态的一致性与正确性,此类对象只能在一个服务实例中运行。可以通过Redis构建分布式锁来实现这一点。当多个实例同时运行时,只有一个实例能够获取分布式锁并执行计算任务。
Redisson 示例:
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class DistributedLockExample {public static void main(String[] args) {Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);RLock lock = redisson.getLock("myLock");lock.lock();try {// 执行业务逻辑System.out.println("Lock acquired, executing business logic.");} finally {lock.unlock();redisson.shutdown();}}
}
2. 处理纯函数与无状态对象
如果函数是纯函数或对象是无状态的,这意味着函数的执行无副作用,可以在多个实例上并行运行。在这种情况下,尽管多个实例同时处理请求,但由于函数和对象的无状态特性,可以确保结果的正确性。
然而,纯函数和无状态对象的并行计算无法实现运算负载的均衡。为此,可以通过Redisson Executor Service构建分布式执行引擎,将函数和对象分布到不同的节点上计算,以充分利用系统资源。
Redisson 分布式执行引擎示例:
Redisson Executor Service 分布式执行引擎示例:
import org.redisson.Redisson;
import org.redisson.api.RExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ExecutorOptions;
import org.redisson.api.executor.TaskSuccessListener;
import org.redisson.api.executor.TaskFailureListener;import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;public class DistributedExecutionExample {public static void main(String[] args) throws Exception {// 配置Redisson客户端Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);// 定义ExecutorOptionsExecutorOptions options = ExecutorOptions.defaults().taskRetryInterval(10, TimeUnit.MINUTES);// 获取RExecutorService实例RExecutorService executorService = redisson.getExecutorService("myExecutor", options);// 提交Runnable任务executorService.submit(new RunnableTask(123));// 提交Callable任务并获取结果Future<Long> future = executorService.submit(new CallableTask());Long result = future.get();System.out.println("Callable任务结果: " + result);// 提交Lambda任务Future<Long> lambdaFuture = executorService.submit((Callable<Long> & Serializable) () -> {System.out.println("Lambda任务已执行!");return 100L;});Long lambdaResult = lambdaFuture.get();System.out.println("Lambda任务结果: " + lambdaResult);redisson.shutdown();}// 定义Callable任务public static class CallableTask implements Callable<Long>, Serializable {private static final long serialVersionUID = 1L;@org.redisson.api.annotation.RInjectprivate transient RedissonClient redissonClient;@org.redisson.api.annotation.RInjectprivate transient String taskId;@Overridepublic Long call() throws Exception {RMap<String, Integer> map = redissonClient.getMap("myMap");Long result = 0L;for (Integer value : map.values()) {result += value;}return result;}}// 定义Runnable任务public static class RunnableTask implements Runnable, Serializable {private static final long serialVersionUID = 1L;@org.redisson.api.annotation.RInjectprivate transient RedissonClient redissonClient;@org.redisson.api.annotation.RInjectprivate transient String taskId;private long param;public RunnableTask() {}public RunnableTask(long param) {this.param = param;}@Overridepublic void run() {RAtomicLong atomic = redissonClient.getAtomicLong("myAtomic");atomic.addAndGet(param);System.out.println("Runnable任务已执行,参数:" + param);}}
}
Worker 注册示例:
import org.redisson.Redisson;
import org.redisson.api.RExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.api.executor.WorkerOptions;public class WorkerRegistrationExample {public static void main(String[] args) {// 配置Redisson客户端Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);// 定义WorkerOptionsWorkerOptions options = WorkerOptions.defaults().setWorkers(2) // 定义使用的Worker数量.setTaskTimeout(60, TimeUnit.SECONDS) // 设置任务超时时间.addListener(new TaskSuccessListener<Long>() {@Overridepublic void onSucceeded(String taskId, Long result) {System.out.println("任务 " + taskId + " 成功完成,结果: " + result);}}).addListener(new TaskFailureListener() {@Overridepublic void onFailed(String taskId, Throwable exception) {System.out.println("任务 " + taskId + " 失败,异常: " + exception.getMessage());}});// 获取RExecutorService实例并注册WorkersRExecutorService executor = redisson.getExecutorService("myExecutor");executor.registerWorkers(options);// Redisson节点无需包含任务类,任务类由Redisson节点的ClassLoader自动加载redisson.shutdown();}
}
性能与限制
Redisson Executor Service 的性能表现
Redisson Executor Service 通过利用 Redis 作为任务队列,实现了分布式任务的调度与执行。这种架构在以下场景下表现出色:
-
高并发任务处理:
- 优势:Redis 的高吞吐量使得 Redisson Executor Service 能够快速地提交和分发任务,适用于大量短时间内需要处理的任务。
- 优化建议:确保 Redis 服务器具备足够的资源(如内存和网络带宽),以应对高并发需求。使用 Redis 集群来分担负载,提升系统的整体吞吐量。
-
延迟敏感型任务:
- 优势:由于任务调度和执行的低延迟特性,适用于需要快速响应的应用场景,如实时数据处理和即时反馈系统。
- 优化建议:优化网络延迟,部署 Redis 服务器尽量靠近应用服务器。同时,合理配置 Redisson 的线程池,确保任务能够及时被处理。
-
长时间运行的任务:
- 限制:Redisson Executor Service 更适用于短时间内完成的任务。对于长时间运行的任务,可能会占用大量资源,导致其他任务的延迟增加。
- 优化建议:将长时间运行的任务拆分为多个子任务,通过批处理或工作流管理来处理。同时,监控任务的执行时间,设置合理的任务超时时间(
taskTimeout
),避免资源被单个任务长时间占用。
-
任务依赖与复杂流程:
- 限制:Redisson Executor Service 主要适用于独立的任务执行,对于有复杂依赖关系的任务流程管理能力有限。
- 优化建议:结合其他工作流引擎(如 Apache Airflow 或 Spring Batch)来管理复杂的任务依赖关系,同时使用 Redisson Executor Service 处理独立的子任务。
潜在限制
-
单点瓶颈:
- 问题:虽然 Redis 本身支持高性能,但在极端高负载情况下,单个 Redis 节点可能成为性能瓶颈。
- 解决方案:采用 Redis 集群架构,将数据和任务负载分散到多个 Redis 节点,以提升整体性能和可用性。
-
任务持久性与可靠性:
- 问题:如果 Redis 实例发生故障,尚未处理的任务可能会丢失,影响系统的可靠性。
- 解决方案:启用 Redis 持久化(RDB 或 AOF),并配置 Redis 主从复制,确保数据在节点故障时可以快速恢复。此外,结合 Redisson 的任务重试机制,确保任务不因临时故障而丢失。
-
网络依赖性:
- 问题:Redisson Executor Service 依赖于网络连接 Redis,如果网络不稳定,可能导致任务提交失败或执行延迟。
- 解决方案:部署 Redis 服务器和应用服务器在同一数据中心或局域网内,减少网络延迟和抖动。使用高可用的网络架构,确保网络的稳定性和可靠性。
-
任务序列化开销:
- 问题:任务和结果对象需要序列化和反序列化,可能带来性能开销,特别是在任务数据量较大时。
- 解决方案:优化任务对象的序列化方式,选择高效的序列化协议(如 Kryo 或 Protostuff),减少序列化和反序列化的时间开销。
容错与可靠性
故障恢复机制
-
任务重试机制:
- 实现方式:Redisson Executor Service 支持任务的自动重试,当任务执行失败或超时后,可以根据配置的重试间隔(
taskRetryInterval
)自动重新提交任务。 - 优化建议:根据任务的重要性和执行环境,合理配置重试次数和间隔时间,避免过度重试导致系统负载过高。同时,结合幂等性设计,确保任务在多次重试后仍能保证数据一致性。
- 实现方式:Redisson Executor Service 支持任务的自动重试,当任务执行失败或超时后,可以根据配置的重试间隔(
-
任务确认机制:
- 实现方式:通过任务监听器(如
TaskSuccessListener
和TaskFailureListener
),可以实时监控任务的执行状态,及时处理执行成功或失败的任务。 - 优化建议:在任务失败时,结合监控系统(如 Prometheus 和 Grafana)触发告警,快速响应并修复潜在问题。同时,可以根据失败原因,动态调整任务的执行策略。
- 实现方式:通过任务监听器(如
-
数据备份与持久化:
- 实现方式:启用 Redis 的持久化机制(RDB 或 AOF),确保任务队列的数据在 Redis 意外重启或宕机时能够快速恢复。
- 优化建议:结合 Redis 集群和主从复制,部署多副本以提升数据的持久性和可用性。同时,定期备份 Redis 数据,防止数据丢失。
容错机制
-
高可用 Redis 部署:
- 实现方式:通过 Redis Sentinel 或 Redis 集群,实现 Redis 的自动故障转移和主从切换,确保 Redis 服务的高可用性。
- 优化建议:合理配置 Sentinel 或 Redis 集群,设置合适的故障检测和自动恢复策略,确保在 Redis 节点故障时能够迅速切换到健康节点,最小化服务中断时间。
-
分布式锁的健壮性:
- 实现方式:在管理有状态对象时,使用 Redisson 提供的分布式锁机制,确保在多个实例中只有一个实例能够持有锁并执行任务。
- 优化建议:合理设置锁的自动释放时间,防止因实例故障导致锁无法释放。同时,结合锁续租机制,确保在长时间任务执行时锁不会意外过期。
-
冗余服务实例:
- 实现方式:部署多个服务实例,并通过负载均衡器(如 Nginx 或 HAProxy)进行流量分配,避免单点故障导致服务不可用。
- 优化建议:结合自动伸缩(Auto Scaling)策略,根据系统负载动态调整服务实例的数量,确保在高负载时仍能保持高可用性。同时,定期健康检查服务实例,及时处理故障实例。
-
监控与报警:
- 实现方式:部署全面的监控系统,实时监控 Redis 和 Redisson Executor Service 的性能指标(如任务队列长度、任务执行时间、错误率等),并配置告警机制。
- 优化建议:使用 Prometheus 收集指标数据,并通过 Grafana 可视化展示。同时,设置多渠道告警(如邮件、短信、钉钉等),确保在出现异常时能够快速响应和处理。
灾难恢复策略
-
跨数据中心冗余:
- 实现方式:将 Redis 集群部署在多个数据中心,确保在某个数据中心发生灾难性故障时,其他数据中心能够继续提供服务。
- 优化建议:配置异地复制(如 Redis 的跨集群复制),确保数据在不同数据中心同步更新。同时,定期进行跨数据中心的故障演练,确保灾难恢复方案的有效性。
-
备份与恢复测试:
- 实现方式:定期备份 Redis 数据,并在需要时进行恢复测试,确保备份数据的完整性和可用性。
- 优化建议:采用增量备份和全量备份相结合的策略,减少备份时间和存储空间。同时,自动化恢复流程,确保在需要恢复时能够快速执行,最小化系统的停机时间。
通过以上的性能优化和容错机制设计,可以大幅提升 Redisson Executor Service 在分布式有状态服务中的表现和可靠性,确保系统在各种场景下都能稳定、高效地运行。
结论
为了避免传统主备切换中的资源浪费,可以将有状态服务拆分为数据、纯函数和对象,通过数据持久化和分布式计算实现高效扩展。利用 Redis 提供分布式锁和持久化支持,并借助 Redisson 实现分布式任务调度和并行计算,有状态的任务通过加锁在单实例上运行,无状态的任务则在多个实例间并行分发。此策略不仅提升了资源利用率,还增强了系统的可靠性和可扩展性。
相关文章:
高效利用资源:分布式有状态服务的高可靠性设计
在分布式系统设计中,实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时,备服务接管任务,例如通过Keepalive实现VIP的切换以保证可用性。然而,这种方式存在资源浪费的问题,因为备服务始终处于空转状…...
网络安全中的 SOC 是什么?
当今世界,网络威胁日益增多,确保网络安全已成为各种规模企业的首要任务。网络安全讨论中经常出现的一个术语是 SOC,即安全运营中心的缩写。但网络安全中的 SOC 是什么呢? SOC在防御网络威胁、管理安全事件和全天候监控系统方面发…...
QtCreator UI界面 菜单栏无法输入中文
如下图红色所示的区域,直接输入是无法输入中文的: 解决方法:在右边的属性值里输入即可 也可以参考这位同学的解决方法:友情链接...
圆桌对话:AI数字笔迹,数字化时代的重要驱动力 | 2024 AI+数字笔迹创新应用发展论坛
12月6日,以“聚焦创新应用,AI引领赋能”为主题的2024 AI数字笔迹创新应用发展论坛在重庆两江新区举办。本届论坛由重庆市大数据应用发展管理局和重庆两江新区管理委员会联合指导,重庆亲笔签数字科技有限公司主办。 论坛现场一场题为“数字化…...
Tablesaw封装Plot.ly实现数据可视化
上文介绍tablesaw的数据处理功能,本文向你展示其数据可视化功能,并通过几个常用图表示例进行说明。 Plot.ly包装 可视化是数据分析的重要组成部分,无论你只是“查看”新数据集还是验证机器学习算法的结果。Tablesaw是一个开源、高性能的Java…...
在Linux(ubuntu22.04)搭建rust开发环境
1.安装rust 1.安装curl: sudo apt install curl 2.安装rust最新版 curl --proto ‘https’ --tlsv1.2 https://sh.rustup.rs -sSf | sh 安装完成后出现:Rust is installed now. Great! 重启当前shell即可 3.检验是否安装成功 rustc --version 结果出现&…...
Less和SCSS,哪个更好用?
前言 Less 和 SCSS 都是流行的 CSS 预处理器,它们的目的都是扩展 CSS 的功能,使样式表更具组织性、可维护性和可重用性。虽然它们有许多相似之处,但在语法、特性和工作方式上也存在一些差异。 Less Less 是一种动态样式表语言,…...
vuex作用及五大组成部分
Vuex 是 Vue.js 官方的状态管理工具,用于管理应用中的全局状态。它的作用主要是解决组件间的状态共享和数据同步问题,特别是在组件复杂嵌套或兄弟组件通信中提供清晰、结构化的解决方案。 Vuex 的作用 集中管理状态: 将组件的共享状态抽取出…...
vue借助西瓜播放器插件实现视频播放
西瓜播放器官网 西瓜播放器 安装 npm install xgplayer 使用案例 vue3为例 <script setup lang"ts"> import Player from xgplayer import { ref, unref, onMounted, watch, onBeforeUnmount, nextTick } from vue import xgplayer/dist/index.min.csscon…...
PHP无法读取.env的配置变量原因
今天帮一个客户在一台服务器配置laravel,在安装好宝塔后,配置了php环境,把laravel项目上传,并且在根目录的.env上配置好数据库等信息后,发现无法正常使用 通过排查发现.env的变量无法正常获取,排查了好久后…...
Android 15(V)新功能适配,雕琢移动细节之美
Android 15,内部代号为Vanilla Ice Cream,是Android移动操作系统的最新主要版本,于2024年2月16日在开发者预览版1中发布。Android 15源代码于 2024年9月4日发布。Android 15稳定版于2024年10月15日发布。 以下是针对 Android 15(…...
Qt自定义类型在信号槽中的使用
引言 示例自定义数据类型信号槽效果检查代码注册自定义类型信号槽使用QVariant传递参数总结附加绑定信号槽,传递的参数如果是自定义类型的变量,槽函数不会响应。为什么呢?是因为自定义类型没有被写入元对象系统,对于Qt来说,不认识这个数据类型,Qt是以事件来驱动的,信号槽…...
自适应卡尔曼滤波(包括EKF、UKF、CKF等)的创新思路——该调什么、不该调什么
在调节自适应卡尔曼滤波时,需要注意的参数和矩阵都对滤波器的性能有直接影响。本文给出详细的说明,包括相关公式和 MATLAB 代码示例 文章目录 需要调节的参数1. **过程噪声协方差矩阵 Q Q Q**:2. **测量噪声协方差矩阵 R R R**:…...
Ape-DTS:开源 DTS 工具,助力自建 MySQL、PostgreSQL 迁移上云
Ape-DTS 是一款高效、轻量级且功能强大的开源工具,专注于解决数据迁移、同步、校验、订阅与加工的需求。无论是将自建的 MySQL/PostgreSQL 数据库迁移到云端,还是在不同数据库间进行数据迁移,Ape-DTS 都能为您提供便捷且可靠的解决方案。它特…...
SpringBoot中使用MyBatis-Plus详细介绍
目录 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 2.定义Mapper(也叫dao)层的接口 3.MyBatis-Plus中常用注解 4. 使用MyBatis-Plus时要做如下配置 5.条件构造器 Wrapper 一、MyBatis-Plus的使用步骤 1.引入MybatisPlus的起步依赖 My…...
Buuctf Web题解
写在前面, 本人小白一枚,记录一下web做题过程,大部分为个人理解可能有些地方写的不够明确还请见谅。当然由于刚入手web题,所以有些题会没有思路,这时会参考其他大佬的题解过程。本文会一直更新,由于是第一次…...
Linux 支持多个spi-nor flash
1. 需求 通常在嵌入式开发过程中可能会遇到需要再同一个SPI总线上挂载多个spi nor flash才能满足存储需求。 2. 技术简介 对于spi-nor flash驱动通常不需要驱动开发人员手搓,一般内核会有一套固定的驱动,而且走的是内核的MTD子系统那一套,市…...
APP、小程序对接聚合广告平台,有哪些广告变现策略?
开发者对接聚合广告平台,可以让自身流量价值最大化,获得更多的广告曝光机会,对接单一的广告联盟容易造成广告填充不足,收益不稳定的问题。#APP广告变现# APP开发者根据应用的生命周期、用户特征和产品定位,选择最适合…...
RPC设计--应用层缓冲区,TcpBuffer
为什么需要应用层的buffer 为了方便数据处理,从fd上直接读写然后做包的组装、拆解不够方便方便异步发送,将数据写到应用层buffer后即可返回,让epoll即event_loop去异步发送。提高发送效率,多个小包可合并发送 buffer 设计 可以…...
微服务的问题
1.创建maven项目 然后配置对应的maven地址 2.创建父工程 删掉其中的src文件 在父pom中进行版本依赖和管理 如下图所示 3.在子文件中进行添加依赖 然后刷新maven进行下载...
开源模型应用落地-知识巩固-如何正确搭建生产级AI服务(一)
一、前言 将大语言模型集成至vllm,能够显著实现推理加速,让模型在处理任务时更加高效快捷,极大地提升了响应速度,减少用户等待时间。具体而言,一方面它能大幅提高吞吐量,vLLM 借助 PagedAttention巧妙地对attention中缓存的张量进行高效管理,从而达成比 HuggingFace Tra…...
Uniapp Android SpringBoot3 对接支付宝支付(最新教程附源码)
Uniapp Android SpringBoot3 对接支付宝支付(最新教程附源码) 1、效果展示2、后端实现2.1 引入支付宝SDK依赖 pom.xml2.2 配置 application.yml2.3 支付宝相关代码2.3.1 AlipayConfig.java2.3.2 ZfbPayConfig.java2.3.3 支付接口2.3.4 支付回调处理接口&…...
SpringSpringBoot常用注解
Spring 和 Spring Boot 是 Java 开发中广泛使用的框架,它们提供了许多注解来简化配置和开发过程。以下是一些 Spring 和 Spring Boot 中常用的注解: Spring 常用注解 Component 用于标注一个类为 Spring 容器的一个组件,Spring 会自动…...
【机器人】振动分析和控制工具之Bode图
Bode 图完整介绍 Bode 图由两个部分组成: 幅值图 (Magnitude Plot):描述系统对不同频率输入信号的增益大小(幅值响应)。相位图 (Phase Plot):描述系统输出信号相对于输入信号的相位差。 Bode 图的横轴是频率&#x…...
基于SpringBoot的“外卖点餐系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“外卖点餐系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能图 用户功能界面 订单管理界面 配送单管理…...
第十七章 使用 MariaDB 数据库管理系统
1. 数据库管理系统 数据库是指按照某些特定结构来存储数据资料的数据仓库。在当今这个大数据技术迅速崛起的年代,互联网上每天都会生成海量的数据信息,数据库技术也从最初只能存储简单的表格数据的单一集中存储模式,发展到了现如今存储海量…...
sql多表联查图文
内连接(INNER JOIN) 语法: SELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.列名 表2.列名;示例: SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.列名 表2.列名;左外连接(LEFT JOIN) 语法 SELECT 列名 FROM…...
网络安全——防火墙
基本概念 防火墙是一个系统,通过过滤传输数据达到防止未经授权的网络传输侵入私有网络,阻止不必要流量的同时允许必要流量进入。防火墙旨在私有和共有网络间建立一道安全屏障,因为网上总有黑客和恶意攻击入侵私有网络来破坏,防火…...
单独测试 pyautogui 的鼠标点击功能,确保它能够在当前环境中正常工作,鼠标自动点击的录制回放功能
感谢您提供的详细日志信息。根据您的反馈,问题可能出在 pyautogui 没有正确获取鼠标焦点或无法在预期的位置执行点击操作。我们将采取以下步骤来进一步诊断和解决这个问题: 1. **确保 pyautogui 正确执行点击操作**: - 我们将添加更多的调…...
图片底部空白缝隙解决法方案(CSS)
当我想实现一个垂直轮播图时,图片底部会出现一个空白缝隙导致切换轮播图片显示不完整。 这里可以用两个方法解决 一、给图片添加(垂直对齐)vertical-align:baseline|middle|top; vertical-align属性的值可以是 (1)关键字值:baseline|midd…...
URI 未注册(设置 语言和框架 架构和 DTD)
一、问题描述:在springboot项目中的resources中新建mybatis-config.xml文件时,从mybatis文档中复制的代码报错:URI 未注册(设置 | 语言和框架 | 架构和 DTD) 二、解决:在Springboot项目的设置->架构和DTD中添加 红色的网址&…...
STL-string类
目录 string类的意义 C语言原始的字符串 字符串类题目 string类 string类文档 auto和范围for auto是个关键字 范围for string类的接口 string的模拟实现 浅拷贝 深拷贝 写时拷贝 string类的意义 C语言原始的字符串 字符串是以\0结尾的字符的合集,为了方便操作,C标准库提…...
HTML前端开发-- Iconfont 矢量图库使用简介
一、SVG 简介及基础语法 1. SVG 简介 SVG(Scalable Vector Graphics)是一种基于 XML 的矢量图形格式,用于在网页上显示二维图形。SVG 图形可以无限缩放而不会失真,非常适合用于图标、图表和复杂图形。SVG 文件是文本文件&#x…...
C++的一些经典算法
以下是C的一些经典算法: 一、排序算法 冒泡排序(Bubble Sort) 原理: 它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换…...
LNMP和Discuz论坛
文章目录 LNMP和Discuz论坛1 LNMP搭建1.1 编译安装nginx服务1.1.1 编译安装1.1.2 添加到系统服务 1.2 编译安装MySQL服务1.2.1 准备工作1.2.2 编辑配置文件1.2.3 设置路径环境变量1.2.4 数据库初始化1.2.5 添加mysqld系统服务1.2.6 修改mysql的登录密码 1.3 编译安装PHP服务1.3…...
华为开源自研AI框架昇思MindSpore应用案例:基于MindSpore框架的SGD优化器案例实现
SGD优化器基本原理讲解 随机梯度下降(SGD)是一种迭代方法,其背后基本思想最早可以追溯到1950年代的Robbins-Monro算法,用于优化可微分目标函数。 它可以被视为梯度下降优化的随机近似,因为它用实际梯度(从…...
μC/OS-Ⅱ源码学习(3)---事件模型
快速回顾 μC/OS-Ⅱ中的多任务 μC/OS-Ⅱ源码学习(1)---多任务系统的实现 μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下) 本文开始,进入事件源码的学习。 事件模型 在一个多任务系统里,各个任务在系统的统筹下相继执行,由于执行速度极快&a…...
UnityShaderLab 实现黑白着色器效果
实现思路:取屏幕像素的RGB值,将三个通道的值相加,除以一个大于值使颜色值在0-1内,再乘上一个强度值调节黑白强度。 在URP中实现需要开启Opaque Texture ShaderGraph实现: ShaderLab实现: Shader "Bl…...
【Linux】文件管理必备知识和基本指令
【Linux】文件管理必备知识和基本指令 什么是操作系统什么是文件什么是路径01. ls 指令02. pwd命令03. cd 指令04. touch指令05.mkdir指令(重要):06.rmdir指令 && rm 指令(重要):rmdir指令rm指令 0…...
移远EC200A-CN的OPENCPU使用GO开发嵌入式程序TBOX
演示地址: http://134.175.123.194:8811 admin admin 演示视频: https://www.bilibili.com/video/BV196q2YQEDP 主要功能 WatchDog 1. 守护进程 2. OTA远程升级 TBOX 1. 数据采集、数据可视化、数据上报(内置Modbus TCP/RTU/ASCII,GPS协…...
CSS 浮动定位
浮动定位 float : 浮动定位 left 左浮动right 右浮动 clear : 清除浮动 leftrightboth 浮动定位会导致 元素脱离正常文档流 、 对应的 父 元素 也可能会产生 高度坍塌 。 解决 父元素 高度坍塌的方案有: 1) 父元素 添加 overflow , 值 为 除 visible 之…...
vmware vsphere5---部署vCSA(VMware vCenter Server)附带第二阶段安装报错解决方案
声明 因为这份文档我是边做边写的,遇到问题重新装了好几次所以IP会很乱 ESXI主机为192.168.20.10 VCSA为192.168.20.7,后台为192.168.20.7:5480 后期请自行对应,后面的192.168.20.57请对应192.168.20.7,或根据自己的来 第一阶段…...
Android Webview 详解
一 简介 一个基于webkit引擎、展现web页面的控件 Android 4.4前:Android Webview在低版本 & 高版本采用了不同的webkit版本的内核Android 4.4后:直接使用了Chrome内核 1.1 作用 在 Android 客户端上加载h5页面在本地 与 h5页面实现交互 & 调用…...
如何使用程序查询域名whois信息?
直接使用TCP协议向WHOIS服务器的43端口发送查询请求即可返回WHOIS信息。 一些国际域名(.COM/.NET/.CC等)需要继续向各注册商的WHOIS服务服务发送查询请求来获取详细信息。 大部分New gTLD来说,服务器是“whois.nic.[后缀]”,例如.red的WHOIS服务器为whoi…...
解决view-ui-plus 中表单验证不通过问题,select 组件开启multiple模式 总是提示错误,即使不验证也提示,有值也验证失败
😉 你好呀,我是爱编程的Sherry,很高兴在这里遇见你!我是一名拥有十多年开发经验的前端工程师。这一路走来,面对困难时也曾感到迷茫,凭借不懈的努力和坚持,重新找到了前进的方向。我的人生格言是…...
复杂系统如何架构?
一张图看懂整个后端系统架构 下图展示了整个后端系统架构,包括数据库、应用服务器、API网关等,展示了它们是如何协同工作的。 一些小贴士 CDN是现代互联网架构中不可或缺的一部分,特别是对于那些需要向全球用户提供高性能和高可用性服务的网站…...
leetcode 3224. 使差值相等的最少数组改动次数
题目链接:3224. 使差值相等的最少数组改动次数 题目: 给你一个长度为 n 的整数数组 nums ,n 是偶数 ,同时给你一个整数 k 。 你可以对数组进行一些操作。每次操作中,你可以将数组中任一元素替换为 0 到 k 之间的任一…...
C# 小案例(IT资产管理系统)
开发工具:visual studio 2022 语言:C# 数据库:Sql Server 2008 页面展示 一、登录 二、主窗体 三、用户管理 四、资产管理 五、关于 Java版地址:基于若依开发物品管理系统(springbootvue)_若依物品管理系统-CSDN博客 Python版…...
React第十四节useState使用详解差异
一、useState() Hook 使用 useState视图更新用法 1、写法: import { useState } from react const [name, setName] useState(Andy)利用数组解构写法, 第一个参数是自定义的属性,用于初始化时候渲染,如上面代码,初…...
ubuntu 安装 docker详细教程
1. 准备工作 1.1系统更新 sudo apt update sudo apt upgrade -y 1.2 检查系统版本 lsb_release -a 2.安装docker 2.1. 安装依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common 2.2 添加docker 官方GPG密钥 curl -fsSL https…...