Error Channel

Error Channel의 μ—­ν• 

μž₯μ•  격리:

  • 였λ₯˜κ°€ λ°œμƒν–ˆμ„ λ•Œ 전체 μ‹œμŠ€ν…œμ΄ μ€‘λ‹¨λ˜λŠ” 것을 λ°©μ§€ν•˜κ³ , λ¬Έμ œκ°€ μžˆλŠ” λ©”μ‹œμ§€λ§Œ λΆ„λ¦¬ν•˜μ—¬ μ²˜λ¦¬ν•©λ‹ˆλ‹€. 이둜 인해 전체 μ„œλΉ„μŠ€μ˜ κ°€μš©μ„±κ³Ό μ•ˆμ •μ„±μ΄ ν–₯μƒλ©λ‹ˆλ‹€.

진단 및 디버깅:

  • 였λ₯˜ 토픽에 μ „μ†‘λœ λ©”μ‹œμ§€λ₯Ό λΆ„μ„ν•˜μ—¬ μ–΄λ–€ λ¬Έμ œκ°€ λ°œμƒν–ˆλŠ”μ§€ μ‰½κ²Œ νŒŒμ•…ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 였λ₯˜ 메타데이터(예: 였λ₯˜ 원인, μŠ€νƒ 트레이슀)와 ν•¨κ»˜ μ €μž₯되기 λ•Œλ¬Έμ— 문제의 원인을 μ°ΎλŠ” 데 도움이 λ©λ‹ˆλ‹€.

재처리:

  • 였λ₯˜μ˜ 원인을 ν•΄κ²°ν•œ ν›„ 였λ₯˜ 토픽에 μžˆλŠ” λ©”μ‹œμ§€λ₯Ό λ‹€μ‹œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 μΌμ‹œμ μΈ 였λ₯˜λ‘œ 인해 μ‹€νŒ¨ν•œ λ©”μ‹œμ§€λ„ λ‚˜μ€‘μ— μ„±κ³΅μ μœΌλ‘œ 처리될 수 μžˆμŠ΅λ‹ˆλ‹€.

λͺ¨λ‹ˆν„°λ§ 및 μ•Œλ¦Ό:

  • Error Channel을 λͺ¨λ‹ˆν„°λ§ν•˜μ—¬ 였λ₯˜ λ°œμƒ λΉ„μœ¨μ΄λ‚˜ νŠΉμ • μž„κ³„κ°’μ„ μ΄ˆκ³Όν•˜λŠ” 경우 μ•Œλ¦Όμ„ 받을 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 μ‹œμŠ€ν…œμ˜ 건강 μƒνƒœλ₯Ό μ§€μ†μ μœΌλ‘œ ν™•μΈν•˜κ³  ν•„μš”ν•œ 쑰치λ₯Ό μ·¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹œμŠ€ν…œ 볡원λ ₯ ν–₯상:

  • Error Channel을 ν™œμš©ν•˜λ©΄ μ‹œμŠ€ν…œμ€ μ˜ˆμƒμΉ˜ λͺ»ν•œ 였λ₯˜μ— λŒ€ν•΄ λ”μš± 탄λ ₯적으둜 λŒ€μ‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 였λ₯˜ λ°œμƒ μ‹œ ν•΄λ‹Ή λ©”μ‹œμ§€λ§Œ λ”°λ‘œ μ²˜λ¦¬ν•˜κ³ , 정상 λ©”μ‹œμ§€λŠ” 계속 처리될 수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€

When user Error Channel ?

μž¬μ²˜λ¦¬κ°€ ν•„μš”ν•œ 경우

μ˜ˆμ‹œ: μ™ΈλΆ€ 결제 μ„œλΉ„μŠ€ 호좜

  • E-commerce μ‹œμŠ€ν…œμ—μ„œλŠ” μ£Όλ¬Έ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  λ•Œ μ™ΈλΆ€μ˜ 결제 μ„œλΉ„μŠ€λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. 이 μ™ΈλΆ€ μ„œλΉ„μŠ€λŠ” λ•Œλ•Œλ‘œ μΌμ‹œμ μΈ 였λ₯˜λ₯Ό λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

public class TemporaryPaymentException extends RuntimeException {
    public TemporaryPaymentException(String message) {
        super(message);
    }
}

@KafkaListener(topics = "order-topic")
public void processOrder(String order) {
    try {
        // ... 주문 둜직 ...
        paymentService.charge(order);
    } catch (TemporaryPaymentException e) {
        // μΌμ‹œμ μΈ 결제 였λ₯˜: Error Channel둜 μ „μ†‘ν•˜μ—¬ λ‚˜μ€‘μ— 재처리
        errorKafkaTemplate.send("payment-retry-topic", order);
    }
}

뢄석이 ν•„μš”ν•œ 경우

μ˜ˆμ‹œ: μœ νš¨ν•˜μ§€ μ•Šμ€ μ£Όλ¬Έ ν˜•μ‹

  • μ£Όλ¬Έ λ©”μ‹œμ§€μ˜ ν˜•μ‹μ΄ μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜ μ˜ˆμƒμΉ˜ λͺ»ν•œ ν•„λ“œλ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” 경우.

public class InvalidOrderFormatException extends RuntimeException {
    public InvalidOrderFormatException(String message) {
        super(message);
    }
}

@KafkaListener(topics = "order-topic")
public void processOrder(String order) {
    try {
        // ... 주문 둜직 ...
        orderValidator.validate(order);
    } catch (InvalidOrderFormatException e) {
        // μœ νš¨ν•˜μ§€ μ•Šμ€ μ£Όλ¬Έ ν˜•μ‹: Error Channel둜 μ „μ†‘ν•˜μ—¬ 뢄석을 μœ„ν•œ μ €μž₯
        errorKafkaTemplate.send("invalid-order-format-topic", order);
    }
}

νŠΉλ³„ν•œ λŒ€μ‘μ΄ ν•„μš”ν•œ 경우

μ˜ˆμ‹œ: 큰 κΈˆμ•‘μ˜ μ£Όλ¬Έ 거절

  • 상점은 일정 κΈˆμ•‘ μ΄μƒμ˜ 주문에 λŒ€ν•΄ μΆ”κ°€ κ²€ν† κ°€ ν•„μš”ν•©λ‹ˆλ‹€. 이런 주문듀은 μžλ™μœΌλ‘œ 거절되고 κ΄€λ¦¬μžμ—κ²Œ μ•Œλ¦Όμ΄ μ „μ†‘λ©λ‹ˆλ‹€.

public class LargeOrderException extends RuntimeException {
    public LargeOrderException(String message) {
        super(message);
    }
}

@KafkaListener(topics = "order-topic")
public void processOrder(String order) {
    try {
        // ... 주문 둜직 ...
        if (orderService.isLargeOrder(order)) {
            throw new LargeOrderException("Order amount exceeds the limit");
        }
    } catch (LargeOrderException e) {
        // 큰 κΈˆμ•‘μ˜ μ£Όλ¬Έ 거절: Error Channel둜 μ „μ†‘ν•˜κ³  κ΄€λ¦¬μžμ—κ²Œ μ•Œλ¦Ό
        errorKafkaTemplate.send("large-order-topic", order);
        notificationService.notifyAdmin(e.getMessage());
    }
}

재처리 방법

μˆ˜λ™ 재처리:

  • κ΄€λ¦¬μž λ˜λŠ” μ—°μ‚°μžκ°€ νŠΉμ • 툴 λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό κ²€ν† ν•˜κ³  μˆ˜λ™μœΌλ‘œ 재처리λ₯Ό κ²°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μžλ™ μž¬μ‹œλ„:

  • Kafka 같은 λ©”μ‹œμ§• μ‹œμŠ€ν…œμ€ λ©”μ‹œμ§€ μ†ŒλΉ„ μ‹€νŒ¨μ‹œ μž¬μ‹œλ„ λ©”μ»€λ‹ˆμ¦˜μ„ 자체적으둜 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 섀정은 Kafka consumer의 섀정을 톡해 μ‘°μ ˆν•  수 μžˆμŠ΅λ‹ˆλ‹€. μž¬μ‹œλ„ 횟수, μž¬μ‹œλ„ 간격 등을 μ„€μ •ν•˜μ—¬ μžλ™μœΌλ‘œ λ©”μ‹œμ§€λ₯Ό μž¬μ²˜λ¦¬ν•˜λ„λ‘ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μŠ€μΌ€μ₯΄λ§λœ 재처리:

  • "payment-retry-topic"와 같은 νŠΉμ • μž¬μ‹œλ„ 토픽에 λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ” 것 외에도, μŠ€μΌ€μ₯΄λ§λœ μž‘μ—…(예: Spring Scheduled Task, Quartz Scheduler λ“±)을 μ‚¬μš©ν•˜μ—¬ μ •κΈ°μ μœΌλ‘œ 이 토픽을 ν΄λ§ν•˜κ³  μž¬μ²˜λ¦¬ν•  λ©”μ‹œμ§€κ°€ μžˆλŠ”μ§€ ν™•μΈν•˜κ³  μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Dead Letter Queue (DLQ):

  • μž¬μ‹œλ„ νšŸμˆ˜κ°€ νŠΉμ • 횟수λ₯Ό μ΄ˆκ³Όν•  경우 λ©”μ‹œμ§€λ₯Ό Dead Letter Queue(DLQ)λΌλŠ” λ³„λ„μ˜ ν† ν”½μœΌλ‘œ 전솑할 수 μžˆμŠ΅λ‹ˆλ‹€. DLQ에 μžˆλŠ” λ©”μ‹œμ§€λŠ” μˆ˜λ™μœΌλ‘œ κ²€ν† λ˜κ³ , 문제λ₯Ό ν•΄κ²°ν•œ ν›„ 재처리될 수 μžˆμŠ΅λ‹ˆλ‹€.

Last updated

Was this helpful?