Spring ‐ Retry - woojin-playground/Backend-PlayGround GitHub Wiki

Retry

  • Spring Retry는 메소드를 호출해서 예외가 발생 했을 때, 자동으로 지정한 메소드를 다시 호출하는 기능을 제공한다. 일시적인 네트워크 접속 장애가 발생했을 때, Failover으로 유용하다.
  • Failover : 시스템 대체 작동, 평소 사용하는 서버와 그 서버의 클론 서버를 가지고 있다가 사용 서버가 장애로 사용이 어렵게 되었을 경우 클론 서버로 그 일을 대신하게 해서 무정지 시스템을 구축하게 해주는 것을 의미한다.

📚 Retry

  • @Retryable is an annotation that specifies retry characteristics for an individual method (with the annotation declared at the method level), or for all proxy-invoked methods in a given class hierarchy (with the annotation declared at the type level).
@Retryable
public void sendNotification() {
    this.jmsClient.destination("notifications").send(...);
}
  • By default, the method invocation will be retried for any exception thrown: with at most 3 retry attempts (maxRetries = 3) after an initial failure, and a delay of 1 second between attempts.
  • A @Retryable method will be invoked at least once and retried at most maxRetries times, where maxRetries is the maximum number of retry attempts. Specifically, total attempts = 1 initial attempt + maxRetries attempts.
  • For example, if maxRetries is set to 4, the @Retryable method will be invoked at least once and at most 5 times.
@Retryable(MessageDeliveryException.class)
public void sendNotification() {
    this.jmsClient.destination("notifications").send(...);
}
  • This can be specifically adapted for every method if necessary — for example, by narrowing the exceptions to retry via the includes and excludes attributes. The supplied exception types will be matched against an exception thrown by a failed invocation as well as nested causes.
@Retryable(includes = MessageDeliveryException.class,
           maxRetries = 4,
           delay = 100,
           jitter = 10,
           multiplier = 2,
           maxDelay = 1000)
public void sendNotification() {
    this.jmsClient.destination("notifications").send(...);
}
  • Or for 4 retry attempts and an exponential back-off strategy with a bit of jitter

📚 @ConcurrencyLimit

@ConcurrencyLimit(10)
public void sendNotification() {
    this.jmsClient.destination("notifications").send(...);
}
  • @ConcurrencyLimit is an annotation that specifies a concurrency limit for an individual method (with the annotation declared at the method level), or for all proxy-invoked methods in a given class hierarchy (with the annotation declared at the type level).
  • This is meant to protect the target resource from being accessed from too many threads at the same time, similar to the effect of a pool size limit for a thread pool or a connection pool that blocks access if its limit is reached.