Fail Fast와 Fail Safe

이도형·2025년 12월 12일

Fail Fast

"문제가 생긴다면 바로 죽여라"

특징

  • 문제가 발생하면 발생 감지되는 즉시 예외를 던지거나 동작을 중단
  • 버그가 숨은 채로 더 진행되는 것을 방지
  • ex. Java Collection의 fail-fast iterator는 순회 중 구조가 바뀌면 바로 ConcurrentModificationException을 던져, 이상한 상태로 진행되는 것을 방지
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FailFastIteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("cherry");

        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String value = it.next();
            System.out.println(value);

            // 컬렉션을 직접 수정 → fail fast
            if ("banana".equals(value)) {
                list.remove(value); // 여기서 ConcurrentModificationException 발생
            }
        }
    }
}

Fail Safe

"문제가 생겨도 최대한 안전하게 계속 돌아가게 하라"

특징

  • 고장이나 오류가 나도 시스템 전체에 피해가 최소가 되도록, 보다 안전한 상태로 동작/정지하도록 설계
  • ex. Java에서 fail safe는 CopyOnWriteArrayListConcurrentHashMap같은 concurrent 컬렉션에서 구현되고, 이들은 복사본(snapshot)을 만들어 순회하므로 원본 수정이 순회에 영향을 주지 않음
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeExample {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("cherry");

        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String value = it.next();
            System.out.println(value);

            // 순회 중 원본 리스트 수정 → 예외 발생 안 함 (fail safe)
            if ("banana".equals(value)) {
                list.add("orange");  // snapshot 기반 순회라 문제없음
            }
        }
        System.out.println("Final list: " + list);  // [apple, banana, cherry, orange]
    }
}

비교

Fail Fast 사용이 유리할 때

  • 개발/테스트 단계 : 버그를 조기 발견해 수정 비용 최소화, (ArrayList로 구조 변경 탐지)
  • 입력 검증 (Objects.requireNonNull, @NotNull로 null 체크)
  • 단일 스레드 환경 : 성능 오버헤드 없고, 잘못된 상태 진행 방지

Fail Safe 사용이 유리할 때

  • 고동시성 환경 : 웹 서버, 메시지 큐에서 읽기/쓰기 동시 발생 시 예외 없이 처리 (CopyOnWriteArrayList)
  • 읽기 중심 워크로드 : 캐시 순회, 로그 처리처럼 빈번한 읽기와 드문 쓰기에 최적
  • 운영 안정성 : 서비스 중단 방지 우선 시 사용

비교 표

활용 시나리오Fail FastFail Safe
개발/디버깅✅ 이상 징후 즉시 발견❌ 변경 무시로 버그 숨김
멀티스레드❌ ConcurrentModificationException✅ 예외 없이 안전 동작
읽기:쓰기 비율균형읽기 >> 쓰기
성능 특성읽기/쓰기 빠름읽기 빠름, 쓰기 느림

결론

Fail Fast -> 테스트 우선
Fail Safe -> 운영 우선
각 기능을 알고 사용하자💡

profile
열심히 살고 싶습니다! 일하고 싶습니다 :)

0개의 댓글