淘宝上传图片api报了“HSF thread pool is full”,很烦但问题还要解!幸亏有这个组件轻松搞定
淘宝上传图片api报了“HSF thread pool is full”,很烦但问题还要解!幸亏有这个组件轻松搞定
又又又报错了:
发现淘宝和都是一个德行,对客端的页面和交互对用户各种谄媚,各种小惊喜,各种体验优化,各种暖心交互,各种闭环;对商端做的真是一坨屎,没有提供场景化完成一个功能的文档,满眼都是鸡零狗碎的东一个西一个的API,文档页面看着老旧丑陋没有技术含量,并且不好,个功能需要半天,没有闭环想用个功能需要各种申请,烦死个人。权限开通后,一个不小心权限就被封功能不能用,又是各种申诉各种整改,憋屈。气死个人。
吐槽又不能解决问题。先来看看这个报错吧。好在淘宝还可以提工单,这点比更有助于解决遇到的问题。
淘宝说我就是这样,也不怕你重试,你再来多请求几次呀!!
既然淘宝方案给了,那就增加重试吧。
自己写一个for循环+sleep来完成重试有些slow+花时间,感觉还是用现成的组件进行重试更优雅。
之前做过技术选型,选了Spring Retry。Spring Retry就不在这展开介绍了,详见文末。
要在Spring框架中基于Spring-Retry实现接口抛异常后的Retryable功能,可以遵循以下步骤:
首先,你需要在你的Spring Boot项目的pom.xml文件中添加spring-retry的依赖。
代码语言:javascript代码运行次数:0运行复制<!-- 重试相关依赖包 -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1..4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
默认是不开启的。
在你的Spring Boot应用的主启动类上添加@EnableRetry注解,以开启重试机制的支持。
代码语言:javascript代码运行次数:0运行复制@SpringBootApplication
@EnableRetry
public class RetryApplication {
public static void main(String[] args) {
SpringApplication.run(, args);
}
}
使用@Retryable注解:
在需要实现重试的方法上添加@Retryable注解,这样当方法抛出指定异常时,就会自动进行重试。
代码语言:javascript代码运行次数:0运行复制import slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import java.ThreadLocalRandom;
@Service
@Slf4j
public class RetryServiceImpl implements RetryService {
@Retryable(value = , maxAttempts = , backoff = @Backoff(delay = 1000, multiplier = 1.5))
@Override
public String doBiz() {
int countVal = ().nextInt(10);
if (countVal > 1) {
// 这里可以使自定义异常,@Retryable中value需与其一致
log.warn("doBiz 执行业务代码失败 countVal {} ", countVal);
throw new RuntimeException("执行业务代码失败");
}
log.info("doBiz 执行业务代码成功 countVal {} ", countVal);
return "success";
}
}
}
翻译一下:
在上面的例子中,@Retryable
注解的参数含义如下:
value
:指定重试的异常类型,这里是Exception
,表示当抛出Exception
类型异常时会触发重试。maxAttempts
:最大重试次数,这里是次(包括第一次尝试)。backoff
:重试的间隔策略,delay
指定了第一次重试的延迟时间(1000毫秒),multiplier
指定了延迟时间的增长倍数(1.5倍)。
启用详细的日志记录:
在Spring的配置中启用DEBUG级别的日志,这样可以查看Spring Retry的内部工作情况,包括代理创建和重试逻辑。可视化的看到重试的过程
代码语言:javascript代码运行次数:0运行复制# 在application.properties或application.yml中添加
logging.level.springframework.retry=DEBUG
写个测试用例,Run起来
代码语言:javascript代码运行次数:0运行复制import ToolBoxApplication;
import slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.SpringBootTest;
@SpringBootTest(classes = , webEnvironment = SpringBootTest.WebEnvironment.RADOM_PORT)
@Slf4j
class RetryServiceImplTest {
@Autowired
private RetryService retryService;
@Test
void doBiz() {
String result = retryService.doBiz();
log.info("result {} ", result);
}
}
执行结果:
代码语言:javascript代码运行次数:0运行复制2024-12-10 21:21:24.749 IFO 22518 --- [ main] o.s.b.TomcatWebServer : Tomcat started on port(s): 65177 (http) with context path ''
2024-12-10 21:21:24.760 IFO 22518 --- [ main] RetryServiceImplTest : Started RetryServiceImplTest in 2.92 seconds (JVM running for 4.005)
2024-12-10 21:21:24.991 DEBUG 22518 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=0
2024-12-10 21:21:24.999 WAR 22518 --- [ main] RetryServiceImpl : doBiz 执行业务代码失败 countVal 7
2024-12-10 21:21:24.999 DEBUG 22518 --- [ main] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 1000
2024-12-10 21:21:26.004 DEBUG 22518 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=1
2024-12-10 21:21:26.004 DEBUG 22518 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=1
2024-12-10 21:21:26.004 IFO 22518 --- [ main] RetryServiceImpl : doBiz 执行业务代码成功 countVal 0
2024-12-10 21:21:26.004 IFO 22518 --- [ main] RetryServiceImplTest : result success
第二次重试时成功了
可以看到,Spring Retry的debug日志与业务代码中打印日志是一致的。
正常情况下,生产环境是不会开debug日志的,想在重试失败时进行一些操作,譬如打印特殊的日志,譬如发一条告警通知,需要怎么做?在加了@Retryable注解的方法中直接加,肯定是不行的。至于原因,各位大佬想一下为什么
实际上,这种场景Spring Retry也是支持的。你可以使用@Recover注解来指定一个方法,当重试次数耗尽后,这个方法将被调用以进行异常恢复处理。
@Recover注解用于标记一个方法,该方法会在@Retryable注解标记的方法重试后仍然失败时被调用。这个方法可以作为最后的防线,处理重试失败后的情况,比如记录日志、发送告警、或者返回一个默认值等。
代码语言:javascript代码运行次数:0运行复制@Recover
public String doBizRecover(Exception e) {
log.warn("@Recover回调方法执行 重试后仍然没有成功");
return "报错了 " + e.getMessage();
}
多跑几次测试用例,尝试触发重试后仍然失败的场景:
代码语言:javascript代码运行次数:0运行复制2024-12-10 21:1:08.452 IFO 24877 --- [ main] o.s.b.TomcatWebServer : Tomcat started on port(s): 50004 (http) with context path ''
2024-12-10 21:1:08.462 IFO 24877 --- [ main] RetryServiceImplTest : Started RetryServiceImplTest in 2.785 seconds (JVM running for .909)
2024-12-10 21:1:08.690 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=0
2024-12-10 21:1:08.696 WAR 24877 --- [ main] RetryServiceImpl : doBiz 执行业务代码失败 countVal
2024-12-10 21:1:08.697 DEBUG 24877 --- [ main] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 1000
2024-12-10 21:1:09.701 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=1
2024-12-10 21:1:09.701 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=1
2024-12-10 21:1:09.702 WAR 24877 --- [ main] RetryServiceImpl : doBiz 执行业务代码失败 countVal 2
2024-12-10 21:1:09.702 DEBUG 24877 --- [ main] o.s.r.backoff.ExponentialBackOffPolicy : Sleeping for 1500
2024-12-10 21:1:11.207 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=2
2024-12-10 21:1:11.207 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=2
2024-12-10 21:1:11.208 WAR 24877 --- [ main] RetryServiceImpl : doBiz 执行业务代码失败 countVal 4
2024-12-10 21:1:11.208 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=
2024-12-10 21:1:11.208 DEBUG 24877 --- [ main] o.s.retry.support.RetryTemplate : Retry failed last attempt: count=
2024-12-10 21:1:11.209 WAR 24877 --- [ main] RetryServiceImpl : @Recover回调方法执行 重试后仍然没有成功
2024-12-10 21:1:11.209 IFO 24877 --- [ main] RetryServiceImplTest : result 报错了 执行业务代码失败
Spring Retry 提供了一系列优点,使其成为处理暂时性故障和提高应用程序弹性的有力工具:
- 简化编码:
- 开发者无需手动编写重试逻辑,Spring Retry 通过注解和模板方法提供了重试的实现,大大简化了代码。
- 一致的API:
- 提供了一致的API来处理重试,无论是注解方式还是编程式方式,都遵循相同的设计原则。
- 灵活的重试策略:
- 支持自定义重试策略,包括重试次数、重试间隔(包括固定间隔和指数退避策略)以及重试条件。
- 异常处理:
- 允许开发者指定哪些异常应该触发重试,以及定义重试失败后的恢复逻辑。
- 集成AOP:
- 利用Spring AOP(面向切面编程),Spring Retry 可以在不修改业务逻辑代码的情况下,为方法添加重试功能。
- 状态管理:
- 支持有状态的重试,这意味着在重试过程中可以保留异常信息和重试状态。
- 兼容性:
- 与Spring生态系统中的其他组件(如Spring Data、Spring Integration)良好集成。
- 透明性:
- 对于调用者来说,重试是透明的,不需要关心重试的具体实现。
- 回退策略:
- 提供了在重试失败后执行的回退策略,允许开发者定义失败后的处理逻辑。
- 支持:
- 通过实现
RetryListener
接口,可以在重试的不同阶段插入自定义逻辑,如记录日志、更新状态等。
- 通过实现
- 可配置性:
- 允许在全局和方法级别配置重试参数,使得重试策略可以根据不同的业务需求进行调整。
- 提高可靠性:
- 对于可能由于网络问题或服务瞬时不可用而导致失败的操作,重试机制可以显著提高应用程序的可靠性。
- 减少人工干预:
- 自动化的重试减少了对人工干预的依赖,特别是在处理大量事务时。
- 易于测试:
- 由于重试逻辑被封装在Spring Retry中,可以更容易地编写单元测试和集成测试。
阿里P7大佬首次分享Spring Retry不为人知的技巧
本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2024-12-10,如有侵权请联系 cloudcommunity@tencent 删除注解apipoolthread上传图片#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 14 条评论) |
本站网友 北京热线 | 5分钟前 发表 |
@Recover来兜底@Recover注解用于标记一个方法 | |
本站网友 宋山木事件 | 29分钟前 发表 |
Retry | |
本站网友 盐酸氨基葡萄糖胶囊价格 | 3分钟前 发表 |
Retry | |
本站网友 咳嗽吃什么 | 21分钟前 发表 |
正常情况下 | |
本站网友 障眼明片 | 30分钟前 发表 |
1 | |
本站网友 怀孕三个月男胎儿图 | 4分钟前 发表 |
@Recover回调方法执行 重试后仍然没有成功 2024-12-10 21 | |
本站网友 反垃圾 | 2分钟前 发表 |
可视化的看到重试的过程代码语言:javascript代码运行次数:0运行复制# 在application.properties或application.yml中添加 logging.level.springframework.retry=DEBUG光说不练假把式写个测试用例 | |
本站网友 马浩然 | 24分钟前 发表 |
Sleeping for 1000 2024-12-10 21 | |
本站网友 清算业务 | 13分钟前 发表 |
状态管理:支持有状态的重试 | |
本站网友 腺肌症 | 16分钟前 发表 |
1 | |
本站网友 周小刚 | 27分钟前 发表 |
count= 2024-12-10 21 | |
本站网友 武夷山租房 | 18分钟前 发表 |
允许开发者定义失败后的处理逻辑 | |
本站网友 发泄 | 4分钟前 发表 |
至于原因 |