java - lambda 函数中的 Spring Retry 似乎不起作用
问题描述
我有一个用 Spring Boot 构建的 lambda 函数,它对每秒可以接受 10 个请求的服务进行 REST 调用。在这 10 个请求之后,我得到了 403。
事实证明,试图让一种方法在这种约束下工作是很困难的。
目前我的代码看起来像
@Slf4j
@UtilityClass
public class HttpUtil {
private final RestTemplate restTemplate = new RestTemplate();
@Retryable(maxAttempts = 60, backoff = @Backoff(delay = 10000, multiplier = 2))
public ResponseEntity<String> sendPostRequest(@NonNull final MultiValueMap<String, Object> data, @NonNull final String url) {
final HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(data, new HttpHeaders());
return restTemplate.postForEntity(url, request, String.class);
}
}
但是,如果我启动它并检查日志,我可以看到 403 异常被一遍又一遍地抛出,并且似乎没有发生“退避”期。
我试图扩展RetryListenerSupport
以添加更多日志记录,以便我可以看到实际的回退期,但这似乎已被忽略,尽管已加载。这是否需要与 RetryTemplate` 一起使用而不仅仅是注释?
否则我的注释明显有问题吗?还是有一种更简单的方法可以在我的方法上实现“每秒 10 个请求的上限”?
编辑:
配置类
@EnableRetry
@Configuration
public class RetryTemplateConfig {
@Bean
public RetryTemplate retryTemplate() {
final RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.registerListener(new DefaultListenerSupport());
return retryTemplate;
}
}
和一个非常简单的听众
@Slf4j
public class DefaultListenerSupport extends RetryListenerSupport {
@Override
public <T, E extends Throwable> void close(final RetryContext context,
final RetryCallback<T, E> callback, final Throwable throwable) {
log.info("onClose {}", throwable.getMessage());
super.close(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onError(final RetryContext context,
final RetryCallback<T, E> callback, final Throwable throwable) {
log.info("onError {}", throwable.getMessage());
super.onError(context, callback, throwable);
}
@Override
public <T, E extends Throwable> boolean open(final RetryContext context,
final RetryCallback<T, E> callback) {
log.info("onOpen");
return super.open(context, callback);
}
}
干杯
解决方案
使用@Retryable
注解的类需要是 Spring bean,否则您将需要RetryTemplate
直接使用而不是注解。
如果你不希望你的类成为一个 bean,你可以这样做:
private static final RetryTemplate retryTemplate = new RetryTemplate();
static {
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(60);
ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
backOffPolicy.setMultiplier(2);
backOffPolicy.setInitialInterval(10000);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setBackOffPolicy(backOffPolicy);
}
private void doSomething() {
retryTemplate.execute(retryContext -> {
return restTemplate.postForEntity(url, request, String.class);
});
}
推荐阅读
- haskell - 两个应用程序/单子保持单曲面结构但方式略有不同的实际意义是什么?
- ios - Why do my properties and outlets become nil after performing a segue?
- orientation - 在移动设备上从纵向切换到横向时,响应式图像(srcset + 大小)不会缩放
- firebase-realtime-database - Firebase 数据库同时多次更新相同的值
- javascript - 网店购物车安全
- python-3.x - 我需要从 -8 数量级的信号中滤除噪声。请检查我的代码是否有标准化互相关和 savitsky-golay?
- python - 如何使用 SVM 对不平衡数据集进行分类
- javascript - Firebase 和 Vue:如何正确初始化 firebase 和 vuefire?
- javascript - 如何在 gscript 的帮助下在 Google 站点中制作一个按钮,以便它可以获取用户邮件 ID,然后将其存储在 googlesheet 中
- logging - 如何通过 nREPL 查看音色日志?