@Retryable @Recover 를 이용한 redis 장애시 DB 조회하는 fallback 구현하기

Bonjugi·2020년 9월 18일
0

1. Overview

@Cacheable 이용시 redis 를 활용해서 캐싱할수 있다.

관련된 코드는 이전 포스팅 참고해도 되고, spring cache redis 검색해서 나오는 다른 블로그를 참고 하자.

하지만 의존하는 모든 외부 서비스는 장애에 대한 대응을 해야 한다.
예를들어 레디스가 동작하지 않는 동안에는 캐시가 아닌 DB 에서 조회 하도록 fallback 기능이 있어야 한다.

AWS Elasticache 라면 믿고 맡겨도 되겠지 하겠지만 어떤 서비스라도 SLA 100% 를 믿지 않는게 좋다.
장애 뿐만 아니라 일시적인 업데이트 등 순단에 대해서도 우리 서비스의 안정성을 높일수 있다.

이때 spring-retry 의 @Retryable 과 @Recover 를 사용하면 된다.
@Retryable 은 예외 발생시 재시도를 하고, @Recover는 재시도 실패시에 동작하는 어노테이션 이다.

2. 의존성 추가

implementation ("org.springframework.retry:spring-retry")

3. 예제 코드 작성

@Slf4j
@Service
@RequiredArgsConstructor
public class StoreBeaconService {

  private final StoreBeaconRepository storeBeaconRepository;
  private final DtoMapper mapper;

  @CacheEvict(cacheNames = "allBeacons", key = "'allBeacons:'+#storeId")
  public void addBeacon(Long storeId, String beaconNumber) {
    storeBeaconRepository.save(new StoreBeacon(new Beacon(beaconNumber), storeId));
  }

  @Retryable(maxAttempts = 1)
  @Cacheable(cacheNames = "allBeacons", key = "'allBeacons:'+#storeId")
  public List<StoreBeaconSignalHistoryDto> allBeacons(Long storeId) {
    return find(storeId);
  }

  @Recover
  public List<StoreBeaconSignalHistoryDto> allBeacons(Exception e, Long storeId) {
    log.error(e.getMessage());
    return find(storeId);
  }

  private List<StoreBeaconSignalHistoryDto> find(Long storeId) {
    return storeBeacon(storeId).stream()
      .map(x -> mapper.mapToStoreBeaconSignalHistory(1L,
        new StoreBeaconSignalHistory(2L, x, SignalStatus.IN_SIGNAL,
          Collections.emptyList())))
      .collect(Collectors.toList());
  }

  private List<StoreBeacon> storeBeacon(Long storeId) {
    return storeBeaconRepository.findByStoreId(storeId);

  }
}

4. Conclusion

  1. spring-retry 으로 redis 장애발생시 DB를 조회하는 장애 대비 패턴을 구현했다.
  2. spring-retry 만으로는 circuit breaker patternHalp Open 개념이 없다.
  3. circuit breaker pattern 구현이 필요하다면 spring-retry 보다는 spring-cloud-starter-circuitbreaker-spring-retry 를 알아보는게 좋다.

    circuit breaker pattern?
    spring-cloud-circuit-breaker
    spring-cloud-circuit-breaker 예제

0개의 댓글