此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
弹性功能
从 7.0 开始,核心 Spring Framework 包括几个常见的弹性功能, 特别@Retryable
和@ConcurrencyLimit
方法调用的注释。
用@Retryable
@Retryable
是一个通用的注释,用于指定单个方法(在方法级别声明注释),或所有代理调用的给定类层次结构中的方法(在类型级别声明注释)。
@Retryable
public void sendNotification() {
this.jmsClient.destination("notifications").send(...);
}
默认情况下,将针对抛出的任何异常重试方法调用:在初始失败后最多重试 3 次,两次尝试之间有 1 秒的延迟。
如有必要,可以专门针对每种方法进行调整——例如,通过缩小要重试的例外情况:
@Retryable(MessageDeliveryException.class)
public void sendNotification() {
this.jmsClient.destination("notifications").send(...);
}
或者对于 5 次重试尝试和带有一点抖动的指数退避策略:
@Retryable(maxAttempts = 5, delay = 100, jitter = 10, multiplier = 2, maxDelay = 1000)
public void sendNotification() {
this.jmsClient.destination("notifications").send(...);
}
最后但同样重要的@Retryable
也适用于具有响应式返回类型的响应式方法,使用 Reactor 的重试功能装饰管道:
@Retryable(maxAttempts = 5, delay = 100, jitter = 10, multiplier = 2, maxDelay = 1000)
public Mono<Void> sendNotification() {
return Mono.from(...); (1)
}
1 | 这生的Mono 将用重试规范进行装饰。 |
有关各种特征的详细信息,请参阅可用的注释属性 在@Retryable
.
有一个String 具有占位符支持的变体可用于多个属性以及作为中使用的特定类型注释属性的替代方案。 |
用@ConcurrencyLimit
@ConcurrencyLimit
是一个注释,用于指定单个的并发限制方法(在方法级别声明注释),或所有代理调用的给定类层次结构中的方法(在类型级别声明注释)。
@ConcurrencyLimit(10)
public void sendNotification() {
this.jmsClient.destination("notifications").send(...);
}
这是为了保护目标资源不被同时,类似于线程池或连接池的效果,如果达到其限制,则阻止访问。
您可以选择将限制设置为 1,从而有效地锁定对目标 Bean 的访问 实例:
@ConcurrencyLimit(1) (1)
public void sendNotification() {
this.jmsClient.destination("notifications").send(...);
}
1 | 1 是默认值,但指定它会使意图更清晰。 |
这种限制对于虚拟线程特别有用,其中通常有没有线程池限制。对于异步任务,这可以限制在SimpleAsyncTaskExecutor
. 对于同步调用,此注释通过ConcurrencyThrottleInterceptor
自 Spring Framework 1.0 以来,它已可用于与 AOP 一起编程使用 框架。
配置@EnableResilientMethods
请注意,与 Spring 的许多基于 Comments 的核心功能一样,@Retryable
和@ConcurrencyLimit
被设计为元数据,您可以选择接受或忽略。通过 AOP 拦截实现弹性注释的实际处理的最便捷方法是声明@EnableResilientMethods
在相应的配置类上。或者,您可以声明RetryAnnotationBeanPostProcessor
和/或ConcurrencyLimitBeanPostProcessor
单独。