重试框架入门:Spring-RetryGuava-Retry
前言
在日常工作中,随着业务日渐庞大,不可避免的涉及到调用远程服务,但是远程服务的健壮性和网络稳定性都是不可控因素,因此,我们需要考虑合适的重试机制去处理这些问题,最基础的方式就是手动重试,侵入业务代码去处理,再高端一点的通过切面去处理,较为优雅的实现重试,下面,介绍两个重试框架,只需要配置好重启策略及重试任务,即可使用。
重试任务
这里只是模拟传参、相应及异常,具体任务需对应业务
package com.example.test.MessageRetry;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.remoting.RemoteAccessException;@Slf4j
public class RetryTask {/*** 重试方法* @param param* @return*/public static boolean retryTask(String param){log.info("请求参数:{}",param);int i = RandomUtils.nextInt(0,15);log.info("随机数:{}",i);if(i == 0){log.error("参数异常");throw new IllegalArgumentException("参数异常");}else if(i > 10){log.error("访问异常");throw new RemoteAccessException("访问异常");}else if(i % 2 == 0){log.info("成功");return true;}else{log.info("失败");return false;}}
}
Spring-Retry
简介
Spirng-Retry是Spring提供的一个重试框架,为spring程序提供声明式重试支持,主要针对可能抛出异常的调用操作,进行有策略的重试。可以通过代码方式和注解方式实现,主要由重试执行者和两个策略构成:
- RetryTemplet:重试执行者,可以设置重试策略(设置重试上线、如何重试)和回退策略(立即重试还是等待一段时间后重试,默认立即重试,如果需要配置等待一段时间后重试则需要指定回退策略),通过Execute提交执行操作,只有在调用时抛出指定配置的异常,才会执行重试
- 重试策略:
策略 | 方式 |
---|---|
NeverRetryPolicy | 只允许调用RetryCallback一次,不允许重试 |
AlwaysRetryPolicy | 允许无限重试,直到成功,此方式逻辑不当会导致死循环 |
SimpleRetryPolicy | 固定次数重试策略,默认重试最大次数为3次,RetryTemplate默认使用的策略 |
TimeoutRetryPolicy | 超时时间重试策略,默认超时时间为1秒,在指定的超时时间内允许重试 |
ExceptionClassifierRetryPolicy | 设置不同异常的重试策略,类似组合重试策略,区别在于这里只区分不同异常的重试 |
CircuitBreakerRetryPolicy | 有熔断功能的重试策略,需设置3个参数openTimeout、resetTimeout和delegate |
CompositeRetryPolicy | 组合重试策略,有两种组合方式,乐观组合重试策略是指只要有一个策略允许即可以重试,悲观组合重试策略是指只要有一个策略不允许即可以重试,但不管哪种组合方式,组合中的每一个策略都会执行 |
- 重试回退策略:
回退策略 | 方式 |
---|---|
NoBackOffPolicy | 无退避算法策略,每次重试时立即重试 |
FixedBackOffPolicy | 固定时间的退避策略,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒 |
UniformRandomBackOffPolicy | 随机时间退避策略,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒 |
ExponentialBackOffPolicy | 指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier |
ExponentialRandomBackOffPolicy | 随机指数退避策略,引入随机乘数可以实现随机乘数回退 |
- 此外,还需要配置重试时间间隔、最大重试次数以及可重试异常
实现
代码方式
RetryTemplate通过execute提交执行操作,需要准备RetryCallback和RecoveryCallback两个类实例,前者对应的就是重试回调逻辑实例,包装正常的功能操作,RecoveryCallback实现的是整个执行操作结束的恢复操作实例,只有在调用的时候抛出了异常,并且异常是在exceptionMap中配置的异常,才会执行重试操作,否则就调用到excute方法的第二个执行方法RecoveryCallback中
package com.example.test.MessageRetry;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;@Service
@Slf4j
public class SpringRetryService {/*** 重试时间间隔ms,默认1000ms*/private long retryPeriodTime = 5000L;/*** 最大重试次数*/private int maxRetryNum = 3;/*** 哪些结果和异常要重试,key表示异常类型,value表示是否需要重试*/private Map<Class<? extends Throwable>,Boolean> retryMap = new HashMap<>();@Testpublic void test(){retryMap.put(IllegalArgumentException.class,true);retryMap.put(RemoteAccessException.class,true);//构建重试模板RetryTemplate retryTemplate = new RetryTemplate();//设置重试回退操作策略,主要设置重试时间间隔FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();backOffPolicy.setBackOffPeriod(retryPeriodTime);//设置重试策略,主要设置重试次数SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(maxRetryNum,retryMap);retryTemplate.setRetryPolicy(retryPolicy);retryTemplate.setBackOffPolicy(backOffPolicy);Boolean execute = retryTemplate.execute(//RetryCallbackretryContext -> {boolean b = RetryTask.retryTask("aaa");log.info("调用结果:{}",b);return b;},retryContext -> {//RecoveryCallbacklog.info("到达最多尝试次数");return false;});log.info("执行结果:{}",execute);}
}
注解方式
上面我们说到Spring-Retry是Spring提供的,那么,它就支持依赖整合
<!--spring-retry--><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.2.2.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.1</version></dependency>
然后,在启动类上添加开启注解
//表示是否开启重试,属性proxyTargetClass,boolean类型,是否创建基于子类(CGLIB)的代理,而不是标准的基于接口的代理,默认false
@EnableRetry
package com.example.test.MessageRetry;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.remoting.RemoteAccessException;@Slf4j
public class RetryTask {/*** 重试方法* @param param* @return*/public static boolean retryTask(String param){log.info("请求参数:{}",param);int i = RandomUtils.nextInt(0,15);log.info("随机数:{}",i);if(i >-1){log.error("参数异常");throw new IllegalArgumentException("参数异常");
// }else if(i > 10){
// log.error("访问异常");
// throw new RemoteAccessException("访问异常");
// }else if(i % 2 == 0){
// log.info("成功");
// return true;}else{log.info("失败");return false;}}
}
/*** 重试调用方法* @param param* @return* @Retryable注解:**/@Retryable(value = {RemoteAccessException.class,IllegalArgumentException.class},maxAttempts = 3,backoff = @Backoff(delay = 5000L,multiplier = 2))public void call(String param){RetryTask.retryTask(param);}/*** 达到最大重试次数,或抛出了没有指定的异常* @param e* @param param* @return*/@Recoverpublic void recover(Exception e,String param){log.error("达到最大重试次数!!!!!");}
@Testpublic void retry(){springRetryService.call("aaa");}
- @Retryable注解说明
属性 | 说明 |
---|---|
value | 指定重试的异常类型,默认为空 |
maxAttempts | 最大尝试次数,默认3次 |
include | 和value一样,默认为空,当exclude也为空时,默认所有异常 |
exclude | 指定不处理的异常 |
Backoff | 重试策略 |
- @Backoff注解说明:设定重试倍数,每次重试时间是上次的n倍
属性 | 说明 |
---|---|
delay | 重试之间的等待时间(以毫秒为单位),默认0 |
maxDelay | 重试之间的最大等待时间(以毫秒为单位),默认0 |
multiplier | 延迟的倍数,默认0.0 |
delayExpression | 重试之间的等待时间表达式,默认空 |
maxDelayExpression | 重试之间的最大等待时间表达式,默认空 |
multiplierExpression | 指定延迟的倍数表达式,默认空 |
random | 随机指定延迟时间,默认false |
-
@Recover注解说明:当重试到达指定次数时,将要回调的方法
-
@Retryable和@Recover修饰的方法要在同一个类中,且被@Retryable和@Recover标记的方法不能有返回值,这样Recover方法才会生效。由于@Retryable注解是通过切面实现的,因此我们要避免@Retryable 注解的方法的调用方和被调用方处于同一个类中,因为这样会使@Retryable 注解失效。
我们可以看到,Spring-Retry只能针对指定异常重试,不能根据执行结果返回值重试,整体使用也比较死板,下面,看下更加灵活的Guava-Retry。
Guava-Retry
简介
Guava-Retry是谷歌的Guava库的一个小扩展,允许为任意函数调用创建可配置的重试策略,我们可以通过构建重试实例RetryBuilder,来设置重试源、配置重试次数、重试超时时间、等待时间间隔等,实现优雅的重试机制。
- 主要属性
属性 | 说明 |
---|---|
attemptTimeLimiter | 时间限制策略,单次任务执行时间限制,超时终止 |
stopStrategy | 停止重试策略 |
waitStrategy | 等待策略 |
blockStrategy | 任务阻塞策略,即当前任务执行完,下次任务执行前做什么,仅有线程阻塞threadSleepStrategy |
retryException | 重试异常(重试策略) |
listeners | 自定义重试监听器,可用于记录日志等 |
- 时间限制策略
策略 | 说明 |
---|---|
NoAttemptTimeLimit | 对代理方法不添加时间限制,默认 |
FixedAttemptTimeLimit | 对代理方法的尝试添加固定时间限制 |
- 重试策略(重试异常)
策略 | 说明 |
---|---|
retryIfException | 抛出 runtime 异常、checked 异常时都会重试,但是抛出 error 不会重试 |
retryIfRuntimeException | 只会在抛 runtime 异常的时候才重试,checked 异常和error 都不重试 |
retryIfExceptionOfType | 允许我们只在发生特定异常的时候才重试,比如NullPointerException 和 IllegalStateException 都属于 runtime 异常,也包括自定义的error |
retryIfResult | 可以指定你的 Callable 方法在返回值的时候进行重试 |
- 停止策略
策略 | 说明 |
---|---|
StopAfterDelayStrategy | 设定最长执行时间,无论任务执行几次,一旦超时,任务终止,返回RetryException |
StopAfterAttemptStrategy | 设定最大尝试次数,一旦超过,返回重试异常 |
NeverStopStrategy | 一直轮询直到获取期望结果 |
- 等待策略
策略 | 说明 |
---|---|
ExceptionWaitStrategy | 异常时长等待,如果抛出的是指定异常,则从传入的方法中取得等待时间并返回;如果异常不匹配,则返回等待时间为0L |
CompositeWaitStrategy | 复合时长等待,在获取等待时间时会获取多种等待策略各自的等待时间,然后累加这些等待时间 |
FibonacciWaitStrategy | 斐波那契等待策略 |
ExponentialWaitStrategy | 指数等待时长,指数增长,若设置了最大时间,则停止,否则到Long.MAX_VALUE |
IncrementingWaitStrategy | 递增等待,提供一个初始时长和步长,随次数叠加 |
RandomWaitStrategy | 随机等待时长,可以提供一个最大和最小时间,从范围内随机 |
FixedWaitStrategy | 固定等待时长 |
代码
<!--guava-retryer--><dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>2.0.0</version></dependency>
package com.example.test.MessageRetry;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.remoting.RemoteAccessException;@Slf4j
public class RetryTask {/*** 重试方法* @param param* @return*/public static boolean retryTask(String param){log.info("请求参数:{}",param);int i = RandomUtils.nextInt(0,15);log.info("随机数:{}",i);if(i < 3){log.error("参数异常");throw new IllegalArgumentException("参数异常");}else if(i > 10){log.error("访问异常");throw new RemoteAccessException("访问异常");}else if(i % 2 == 0){log.info("成功");return true;}else{log.info("失败");return false;}}
}
package com.example.test.MessageRetry;import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import lombok.extern.slf4j.Slf4j;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service
@Slf4j
public class GuavaRetryService {public void guavaRetry(){//构建重试实例RetryBuilder,可以设置重试源,可以配置重试次数、重试超时时间、等待时间间隔Retryer<Boolean>retryer = RetryerBuilder.<Boolean>newBuilder()//设置异常重试源.retryIfExceptionOfType(RemoteAccessException.class).retryIfExceptionOfType(IllegalArgumentException.class)//设置根据结果重试 res->res==false Predicates.containsPattern("_error$").retryIfResult(Predicates.equalTo(false))//设置等待时间.withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))//设置最大重试次数.withStopStrategy(StopStrategies.stopAfterAttempt(3))//设置重试监听,可用作重试时的额外动作.withRetryListener(new RetryListener() {@Overridepublic <V> void onRetry(Attempt<V> attempt) {log.error("第【{}】次调用失败",attempt.getAttemptNumber());}})//设置阻塞策略.withBlockStrategy(BlockStrategies.threadSleepStrategy())//设置时间限制.withAttemptTimeLimiter(AttemptTimeLimiters.noTimeLimit()).build();try{retryer.call(()->RetryTask.retryTask("aaa"));}catch (Exception e){e.printStackTrace();}}
}
可以看到,我们设置了重试三次,超过这个限制没有执行成功,抛出了重试异常,而且也可以根据我们的返回结果来判断。
总结
Spring-Retry和Guava-Retry都是线程安全的重试框架,能够保证并发业务下重试逻辑的正确性。两者都很好的将正常方法和重试方法进行了解耦,可以设置超时时间、重试次数、间隔时间、监听结果等,相比来说,Guava-Retry比Spring-Retry更加灵活,并且可以通过返回值来进行重试,两者都是非常好的重试框架,具体的选用看相关的业务场景即可。
相关文章:

重试框架入门:Spring-RetryGuava-Retry
前言 在日常工作中,随着业务日渐庞大,不可避免的涉及到调用远程服务,但是远程服务的健壮性和网络稳定性都是不可控因素,因此,我们需要考虑合适的重试机制去处理这些问题,最基础的方式就是手动重试…...
[QCM6125][Android13] 修复PRODUCT_COPY_FILES无法拷贝so
文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: QCM6125 版本: Android 13 kernel: msm-4.14 问题描述 在进行系统移植时,经常会把一些自己开发的c或者c程序编译成so库,然后在系统服务中去调用这些库。所以在进行新代码开发时&am…...

微服务Eureka注册中心
目录 一、Eureka的结构和作用 二、搭建eureka-server 三、服务注册 四、服务发现 假如我们的服务提供者user-service部署了多个实例,如图: 存在的问题: order-service在发起远程调用的时候,该如何得知user-service实例的ip地址…...

Java:企业级java后端开发,需要掌握哪些内容
一、什么是后端开发 后端开发是指开发基于服务器端的软件应用程序,也称为系统的后台或服务器端编程。 后端程序员负责处理网站或应用程序后台的逻辑和功能,包括数据库管理、服务器端脚本编写、API设计、数据安全性、网站性能优化等。 后端开发技术通常包…...
使用Go语言生成Excel任务表依赖图(Markdown文件mermaid图)
一、前言 在游戏中,任务是非常常见的玩法,可能会有主线任务,支线任务以及其它一些类型的任务,各任务可能还会有前置任务,即需要完成某个任务之后,才能做当前任务。在游戏开发中,配置表可以使用…...

C语言和C++的区别在哪?如何自学C++?
C语言和C是两种不同的编程语言,它们在语法、特性和用途上有一些区别。以下是C语言和C的一些主要区别: 面向对象编程:C是一种支持面向对象编程的语言,它在C语言的基础上添加了类、对象、继承、多态等面向对象的特性。而C语言是一种…...
功能强大的开源数据中台系统 DataCap 1.13.0 发布
推荐一套基于 SpringBoot 开发的简单、易用的开源权限管理平台,建议下载使用: https://github.com/devlive-community/authx 推荐一套为 Java 开发人员提供方便易用的 SDK 来与 OpenAI 的 API 进行交互组件:https://github.com/devlive-community/openai…...

JTS Self-intersection异常TopologyException: side location conflict解决办法
JTS Self-intersection异常TopologyException: side location conflict解决办法 举例:问题围栏 MULTIPOLYGON (((114.0905685 32.1120567, 114.0905685 32.112957, 114.0905685 32.1138535, 114.0905685 32.1147537, 114.0905685 32.115654, 114.0905685 32.11655…...

Maven: No compiler is provided in this environment.
在Eclipse中运行Maven项目,报错: No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 解决方法: Windows > Preferences > Java > Installed JREs > Add > Standard VM,…...
.NET-10. 其他-VSTO+VBA
VSTOVBA 前言VSTO 外接程序介绍:VSTO参考链接:VSTO 例子: VBA:参考链接: 前言 主要用于Excel插件。 VSTO 外接程序介绍: Excel、Word、PowerPoint、Project、Visio等等Office应用程序 相对简单 VSTO参考链接&#x…...

相机传感器格式与镜头光圈参数
相机靶面大小 CCD/CMOS图像传感器尺寸(sensor format)1/2’‘、1/3’‘、1/4’实际是多大 1英寸——靶面尺寸为宽12.7mm*高9.6mm,对角线16mm。 2/3英寸——靶面尺寸为宽8.8mm*高6.6mm,对角线11mm。 1/2英寸——靶面尺寸为宽6.…...
Android 设置头像(拍照获取、相册获取、裁剪照片)
在Android原生态开发过程中,往往会设计到用户头像的设置问题,一般来讲设置头像需要用到拍照、获取照片、存储照片、裁剪照片、显示照片等问题,本文将一步一步的进行说明讲解。 首先需要强调几点我在开发过程中遇到的问题。 权限问题…...

android开发之Android 自定义滑动解锁View
自定义滑动解锁View 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 需求效果图如下 实现效果展示 自定义view如下 /** Desc 自定义滑动解锁View Author ZY Mail sunnyfor98gmail.com Date 2021/5/17 11:52 *…...

CAD绘制法兰、添加光源、材质并渲染
首先绘制两个圆柱体,相互嵌套 在顶部继续绘制圆柱体,这是之后要挖掉的部分 在中央位置绘制正方形 用圆角工具: 将矩形的四个角分别处理,效果: 用拉伸工具 向上拉伸到和之前绘制的圆柱体高度齐平 绘制一个圆柱体&#…...

ChatGPT访问流量下降的原因分析
自从OpenAI的ChatGPT于11月问世以来,这款聪明的人工智能聊天机器人就席卷了全世界,人们在试用该工具的同时也好奇该技术到底将如何改变我们的工作和生活。 但近期Similarweb表示,自去ChatGPT上线以来,该网站的访问量首次出现下…...

干货 | 详述 Elasticsearch 向量检索发展史
1. 引言 向量检索已经成为现代搜索和推荐系统的核心组件。 通过将复杂的对象(例如文本、图像或声音)转换为数值向量,并在多维空间中进行相似性搜索,它能够实现高效的查询匹配和推荐。 图片来自:向量数据库技术鉴赏【上…...
mysql常见面试题,高频题目放送
互联网的产品架构是包含这接入层,逻辑处理以及储存层的,其中储存层承载着较多的数据以及持久化的任务,而说到储存层,避免不了说到数据库,在我们面试的时候,数据库的知识题目占比是非常多的: 1.…...

使用 PowerShell 将 Excel 中的每个工作表单独另存为独立的文件
导语:在日常工作中,我们经常需要处理 Excel 文件。本文介绍了如何使用 PowerShell 脚本将一个 Excel 文件中的每个工作表单独另存为独立的 Excel 文件,以提高工作效率。 1. 准备工作 在开始之前,请确保已经安装了 Microsoft Exc…...
python提取pdf图片
import fitz import re import osdef save_pdf_img(path, save_path):path: pdf的路径save_path : 图片存储的路径# 使用正则表达式来查找图片checkXO r"/Type(? */XObject)"checkIM r"/Subtype(? */Image)"# 打开pdfdoc fitz.open(path)# 图片计数im…...

Vue3 表单输入绑定简单应用
去官网学习→表单输入绑定 | Vue.js 运行示例: 代码:HelloWorld.vue <template><div class"hello"><h1>Vue 表单输入绑定</h1><input type"text" placeholder"输入框" v-model"msg"…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...