🔥 TIL-Day 83 Spring AOPによる異常時の再試行
14564 ワード
Exception
が発生すると、Spring AOPを使用して、この方法を自動的に再起動するエージェントが実装される.リクエストが再試行から除外される可能性がある場合は、サーバ側が指定した回数で再試行することはクライアントにとって良い方法です.
ソースコードに触れずに適用したい方法にのみ適用されます.
ソースコードではなく、非ビジネスロジックの再試行ロジックが追加されているため、
@Retry
が適切であり、프록시 패턴
をSpringでより使いやすくするために프록시 패턴
を使用します.📌 依存項目の追加
[ Spring AOP ]
implementation 'org.springframework.boot:spring-boot-starter-aop'
📌 再試行ターゲットとなるテストクラスとメソッドの作成
Spring AOP
のrepository
メソッドは、5回目のアクセスごとに例外が発生します.@Repository
public class ExamRepository {
private static int sequence = 0;
// 5번째 요청마다 예외를 발생시킨다.
public String save(String itemId) {
++sequence;
if (sequence%5 == 0) {
throw new IllegalStateException("예외 발생");
}
return "ok";
}
}
本来は5番目のリクエストごとに1つの例外が返されますが、例外が発生した場合は、再試行することで例外を回避します.📌 Annotationを作成してJoinPointをマーク
再試行コンサルティングは、
save
が添付されている方法に適用される.成功するまで無限の再試行が行われないことを確認し、属性は
@Retry
を含み、異なる方法で最大再試行回数を適用する.@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
int value() default 3;
}
📌 調査の作成
value
の前後では、異常などの他の作業を処理する必要があるため、JoinPoint
が使用される.@Around
言語テストの名前が指定されており、このタイプをパラメータとしているため、PointCutが指定されています.パラメータを受け入れない場合は、@annotation()にパラメータのパケットパスとタイプを含める必要があります.
@annotation(어노테이션_이름)
言語テストから最大再試行回数を取得し、再試行回数に基づいてRetry
を呼び出す.( JoinPoint
);要求に異常が発生した場合、直ちに異常を投げ出すのではなく一時保存し、最大再試行回数を超えると一時保存の異常が発生します.
@Aspect
@Slf4j
public class RetryAspect {
@Around("@annotation(retry)")
public Object doRetry(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
log.info("[Retry] {} retry={}", joinPoint.getSignature(), retry);
int maxRetry = retry.value();
Exception exceptionHolder = null;
for (int retryCnt=1; retryCnt<=maxRetry; retryCnt++) { // 재시도
if (retryCnt > 1) {
log.info("{} 번째 재시도", retryCnt-1);
}
try {
return joinPoint.proceed(); // target 호출시 예외가 없다면 그대로 반환
} catch (Exception e) {
exceptionHolder = e; // 예외가 발생했다면 발생한 예외를 보관
}
}
throw exceptionHolder; // 최대 재시도 횟수를 넘어선 경우 예외발생
}
}
📌 適用前にテスト
これは再試行のために説明書を貼る前のテストです.
@Slf4j
@SpringBootTest
public class RetryTest {
@Autowired
ExamRepository examRepository;
@Test
void test() {
for (int i=1;i<=5;i++) {
String result = examRepository.save(String.valueOf(i));
log.info("result={}, itemId={}", result, i);
}
}
}
1~5の合計5回のリクエストが発生し、4回目のリクエスト以降に異常が発生したことを確認します.📌 適用後のテスト
再試行ロジックを適用する方法に
proceed()
を貼り付け、AOPを適用した.@Repository
public class ExamRepository {
private static int sequence = 0;
// 5번째 요청마다 예외를 발생시킨다.
@Retry
public String save(String itemId) {
++sequence;
if (sequence%5 == 0) {
throw new IllegalStateException("예외 발생");
}
return "ok";
}
}
スプリング容器で再試行が必要なので、@Retry
を使用して登録します.@Import(RetryAspect.class)
@Slf4j
@SpringBootTest
public class RetryTest {
...
}
これで、5番目のリクエストごとに再試行が行われ、リクエストは正常な応答を再試行されます.4番目のリクエストでは、5番目のリクエストが成功したことを確認できます.
📌 リファレンス
以下のコースを100%参考にまとめた内容です.
私は授業資料をそのまま持ってきたわけではありません.もっと正確な情報がほしいなら、私の授業を聞いてください.(強くお勧め!)
インフラ-スプリングコア原理高級編(金英漢)
Reference
この問題について(🔥 TIL-Day 83 Spring AOPによる異常時の再試行), 我々は、より多くの情報をここで見つけました https://velog.io/@dhk22/TIL-Day-83-Spring-AOP를-이용한-예외발생-시-재시도-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol