fallback 패턴

2024. 12. 12. 18:01Spring Microservice

Fallback 패턴: 상세 설명

1. Fallback 패턴이란?

Fallback 패턴은 시스템에서 장애가 발생하거나 특정 작업이 실패할 경우, 대체 로직을 실행해 사용자 경험을 유지하고 시스템 안정성을 높이는 설계 기법입니다. 이 패턴은 장애를 완전히 제거하거나 복구하는 것이 아니라, 장애 상황에서도 적절히 대처할 수 있도록 안전한 대체 경로를 제공합니다.


2. Fallback 패턴의 필요성

문제 상황
  1. 외부 서비스 의존성:
    • 애플리케이션이 외부 API, 데이터베이스, 네트워크 서비스 등과 통신 중 장애가 발생하면 응답 시간이 증가하거나 오류가 반환됩니다.
  2. 사용자 경험 악화:
    • 장애로 인해 사용자에게 오류 메시지를 반환하거나 요청이 지연되면 사용자 경험이 저하됩니다.
  3. 시스템 복잡성 증가:
    • 분산 시스템에서는 하나의 장애가 다른 서비스에 도미노처럼 영향을 미칠 수 있습니다.
Fallback 패턴의 해결 방법
  • 장애 상황에서 안전한 대체 응답을 제공하여 시스템의 신뢰성을 높입니다.
  • 장애가 사용자에게 직접적으로 영향을 미치지 않도록 보호합니다.
  • 장애가 복구되기 전까지 최소한의 기능을 유지합니다.

3. Fallback 패턴의 주요 동작 원리

  1. 장애 감지:

    • 작업이 실패하거나 시간 초과 등의 문제가 발생했는지 확인.
    • 예: 네트워크 호출 실패, HTTP 5xx 응답.
  2. 대체 로직 실행:

    • 작업이 실패하면 대체 로직을 실행하여 사용자에게 적절한 대체 응답을 제공합니다.
    • 대체 로직은 예측 가능한 방식으로 설계되어야 합니다.
  3. 원본 작업 복구:

    • 문제가 해결되면 원본 작업이 정상적으로 복구되어야 합니다.

4. Fallback 패턴의 주요 사용 사례

  1. 외부 API 호출:

    • 외부 API 호출 실패 시 기본 값 또는 캐시 데이터를 반환.
  2. 데이터베이스 장애:

    • 데이터베이스 연결 실패 시 캐시 데이터 사용 또는 기본 응답 반환.
  3. 네트워크 연결 문제:

    • 네트워크 호출 실패 시 미리 정의된 고정 응답 반환.
  4. 서버 과부하:

    • 서버가 과부하 상태일 경우 즉시 fallback으로 전환하여 부하를 완화.

5. Fallback 패턴의 구현 방식

1) 기본값 제공
  • 실패한 작업에 대해 미리 정의된 기본값을 반환합니다.
  • 예시:
    • 서비스 장애 시 Unavailable이라는 문자열을 반환.
    • 데이터베이스 장애 시 "임시 데이터"를 반환.
2) 캐시 데이터 사용
  • 장애 발생 시, 이전에 저장된 캐시 데이터를 반환합니다.
  • 예시:
    • 뉴스 서비스에서 최신 뉴스를 가져오지 못하면 캐시된 뉴스를 반환.
3) 대체 서비스 호출
  • 주 서비스 호출이 실패하면 대체 서비스 또는 백업 서비스를 호출합니다.
  • 예시:
    • 메인 데이터 센터가 다운되면 백업 데이터 센터 호출.
4) 기본 응답 구조 유지
  • 사용자 경험을 유지하기 위해 구조적으로 유사한 데이터를 반환합니다.
  • 예시:
    • "서비스를 사용할 수 없습니다"라는 메시지가 포함된 JSON 반환.
5) 비동기 처리
  • 실패한 작업을 백그라운드 작업으로 전환하여 요청을 즉시 처리하고, 작업 완료 후 사용자에게 알림.

6. Spring Boot와 Resilience4j를 이용한 Fallback 패턴 구현

설정

pom.xml에 Resilience4j 의존성을 추가:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
    <version>2.0.2</version>
</dependency>
Fallback 적용 예제
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;

@Service
public class ExternalService {

    @CircuitBreaker(name = "exampleService", fallbackMethod = "fallbackResponse")
    public String callExternalService() {
        // 외부 API 호출 시뮬레이션
        if (Math.random() > 0.5) { // 실패 시뮬레이션
            throw new RuntimeException("Service Failure");
        }
        return "External Service Response";
    }

    public String fallbackResponse(Throwable t) {
        return "Fallback response due to: " + t.getMessage();
    }
}
Controller에서 서비스 호출
@RestController
@RequestMapping("/api")
public class ExampleController {

    private final ExternalService externalService;

    public ExampleController(ExternalService externalService) {
        this.externalService = externalService;
    }

    @GetMapping("/external")
    public String getExternalServiceResponse() {
        return externalService.callExternalService();
    }
}

7. 장점

  1. 사용자 경험 보호:

    • 장애 시 대체 응답을 제공하여 사용자가 시스템의 가용성을 높게 느끼도록 함.
  2. 시스템 안정성:

    • 장애가 발생한 서비스로의 요청을 줄여 시스템 전체를 보호.
  3. 예측 가능한 동작:

    • 예상치 못한 장애에도 미리 정의된 대체 로직으로 안정적인 응답 제공.

8. 고려 사항 및 단점

  1. 대체 로직 설계의 복잡성:

    • Fallback 로직이 원본 로직만큼 복잡해질 수 있음.
    • 대체 응답의 품질이 낮으면 사용자 경험이 저하될 수 있음.
  2. 일관성 문제:

    • 캐시 데이터를 사용하는 경우 최신 데이터와 일관성이 맞지 않을 수 있음.
  3. 운영 비용 증가:

    • 백업 서비스, 캐시 유지 등 Fallback 로직 유지에 추가 비용 발생.
  4. 복구 지연:

    • Fallback을 과도하게 의존하면 원본 서비스 복구가 지연될 가능성.

9. Fallback 패턴 활용 예시

  1. 이커머스 애플리케이션:

    • 결제 서비스가 실패하면 "잠시 후 다시 시도해 주세요"와 함께 주문 내역을 저장.
  2. 스트리밍 서비스:

    • 동영상 스트리밍이 실패하면 "동영상을 로드할 수 없습니다"라는 메시지와 함께 다른 콘텐츠 추천.
  3. 금융 애플리케이션:

    • 실시간 잔액 조회 실패 시 마지막으로 확인된 잔액을 반환.

추가적으로 더 자세한 예시나 코드 구현을 원하시면 말씀해주세요!

'Spring Microservice' 카테고리의 다른 글

bulkhead 패턴  (0) 2024.12.12
fallback 패턴 활용 예  (0) 2024.12.12
Circuit Breaker 패턴  (0) 2024.12.12
@FeignClient  (0) 2024.12.11
@LoadBalanced  (0) 2024.12.11