[문제 상황]
'getPicture' 메소드는 요약, 번역, 그리고 이미지 생성을 거쳐 이미지 URL을 반환한다. 요청시, 이 메소드가 정상적으로 처리될 때도 있었지만 일부 500 에러가 발생하였다.
[해결 방법]
외부 서비스 호출 시 재시도 로직을 추가해주었다. 일시적인 연결 문제로 예외가 발생한 경우, 1초 대기 후 재시도를 할 수 있게 getPicture()을 수정해 주었다.
[이전 코드]
@GetMapping("/{diary_id}/picture")
public ResponseEntity<?> getPicture(@PathVariable Long diary_id) {
// 요약 및 번역
String summary = clovaSummaryService.summarizeDiary(diary_id);
String engSummary = papagoTranslationService.translateSummary(diary_id);
diaryService.setSummary(diary_id, summary, engSummary);
String imageUrl = stablediffusionService.getTextToImage(diary_id);
Map<String, Object> response = new HashMap<>();
response.put("imageUrl", imageUrl);
return new ResponseEntity<>(response, HttpStatus.OK);
}
[수정 코드]
@GetMapping("/{diary_id}/picture")
public ResponseEntity<?> getPicture(@PathVariable Long diary_id) {
int maxAttempts = 3; // 최대 재시도 횟수
int attempts = 0;
while (attempts < maxAttempts) {
try {
// 요약 및 번역
String summary = clovaSummaryService.summarizeDiary(diary_id);
String engSummary = papagoTranslationService.translateSummary(diary_id);
diaryService.setSummary(diary_id, summary, engSummary);
String imageUrl = stablediffusionService.getTextToImage(diary_id);
Map<String, Object> response = new HashMap<>();
response.put("imageUrl", imageUrl);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (WebClientRequestException e) {
// 재시도 로직을 위해 예외 처리
attempts++;
if (attempts >= maxAttempts) {
// 최대 재시도 횟수를 초과한 경우
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
// 일시적인 연결 문제로 예외가 발생한 경우, 대기 후 재시도
try {
Thread.sleep(1000); // 1초 대기 후 재시도
} catch (InterruptedException ex) {
// 대기 도중 인터럽트가 발생한 경우 예외 처리
Thread.currentThread().interrupt();
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
} catch (Exception e) {
// 다른 예외가 발생한 경우
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// 최대 재시도 횟수를 초과한 경우
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
[2차 수정 코드 - 예외처리 개선]
@GetMapping("/{diary_id}/picture/paint")
public ResponseEntity<?> getPictureV1(@PathVariable Long diary_id) {
return getPictureResponse(diary_id, "V1");
}
@GetMapping("/{diary_id}/picture/pencil")
public ResponseEntity<?> getPictureV2(@PathVariable Long diary_id) {
return getPictureResponse(diary_id, "V2");
}
private ResponseEntity<?> getPictureResponse(Long diary_id, String version) {
int maxAttempts = 10; // 최대 재시도 횟수
int attempts = 0;
while (attempts < maxAttempts) {
try {
String summary = clovaSummaryService.summarizeDiary(diary_id);
String engSummary = papagoTranslationService.translateSummary(diary_id);
temporaryDiaryService.setSummary(diary_id, summary, engSummary);
String imageUrl = version.equals("V1") ?
stablediffusionService.getTextToImageV1(diary_id) :
stablediffusionService.getTextToImageV2(diary_id);
Map<String, Object> response = new HashMap<>();
response.put("imageUrl", imageUrl);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
attempts++;
if (attempts >= maxAttempts) {
log.error("Failed to get the picture after {} attempts. Error: {}", attempts, e.getMessage());
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
log.warn("Failed to get the picture on attempt {}. Retrying...", attempts);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
log.error("Thread interrupted while retrying. Error: {}", ex.getMessage());
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
return new ResponseEntity<>("Failed to get the picture.", HttpStatus.INTERNAL_SERVER_ERROR);
}
'Project' 카테고리의 다른 글
[졸업프로젝트] Lombok의 @ToString StackOverflowError 해결 (0) | 2023.06.05 |
---|