1

결국 일관성있는 분산 아키텍처를 구현하는 것이 고통 스럽습니다. 그것을하는 법에 관한 이야기를 말하는 블로그 포스트의 톤이있다, 그러나 그것을 실제로하는 방법을 (코드) 보여주지 않는다.Spring Cloud Stream Kafka - 최종 일관성 - Kafka는 수신 확인되지 않은 메시지를 자동 재 시도합니까 (autocommitoffset = false 사용시)

내가 겪고있는 측면 중 하나는 그들이 ack'd되지 않은 메시지를 수동으로 다시 시도해야한다는 것입니다.

예 : 내 주문 서비스가 Kafka에게 유료 이벤트를 보냅니다. 결제 서비스는 가입 및 결제 확인 또는 지불 실패로 대답을 처리한다

  1. 지불에 대한 질문 Order Service ----Pay event----> Kafka ----Pay Event ----> Payment Service

  2. 결제 OK : ->Payment Service ----Payment failure event ----> Kafka ----Payment failure Event ----> Order Service ->를 Payment Service ----Payment ok event ----> Kafka ----Payment ok Event ----> Order Service

  3. 결제 실패

점은 다음과 같습니다

동기화 전송을 사용하여 카프카에게 메시지가 배달 된시기를 확실히 알고 있습니다. 그러나 지불 서비스가 지불을 처리했다는 것을 알아야하는 유일한 방법은 응답 이벤트 (지불 확인 | 지불 실패)입니다.

이렇게하면 Order 서버에서 재시도 메커니즘을 구현해야합니다. 잠시 후에 답을 얻지 못하면 새로운 Pay 이벤트를 다시 시도하십시오.

더 많은 것은 이것도 실제로 처리되었지만 응답이 주문 서비스에 도착하지 않은 경우 지불 서비스에서 중복 된 메시지를 처리하도록합니다.

소비자가 메시지의 새 오프셋을 확인하지 않은 경우 Kafka에 재시도를 보낼 수있는 메커니즘이 있는지 궁금합니다.

봄 클라우드 스트림에서 우리는 거짓에 autoCommitOffset 속성을 설정하고 소비자의 오프셋 (offset)의 ACK를 처리 할 수 ​​

우리가 실행되지 않으면 어떻게됩니까
@StreamListener(Sink.INPUT) 
public void process(Message<?> message) { 
    Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class); 
    if (acknowledgment != null) { 
     System.out.println("Acknowledgment provided"); 
     acknowledgment.acknowledge(); 
    } 
} 

acknowledgment.acknowledge(); 메시지가 자동으로 재전송 것 카프카가이 소비자에게?

우리가 더 이상 수동으로 다시 시도 할 필요가 없습니다 것과 같은 물건을 할 수있는 가능한 경우 :

Paymen 서비스 :이 가능했던 경우

@Autowired 
private PaymentBusiness paymentBusiness; 

@StreamListener(Sink.INPUT) 
public void process(Order order) { 
    Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class); 
    if (acknowledgment != null) { 
     paymentBusiness(order);    
     //If we don't get here because of an exception 
     //Kafka would retry... 
     acknowledgment.acknowledge(); 
    } 
} 

, 어떻게 재시도 기간 카프카에서 구성 되었습니까?

시나리오가 최악의 경우 (이 시나리오는 지원되지 않음) 수동으로 다시 시도해야합니다. Kafka를 사용하여 최종 일관성을 다루는 Spring Cloud Stream 앱의 실제 예를 알고 있습니까?

답변

1

acknowledgement.acknowledge()를 실행하지 않으면 어떻게됩니까? 카프카가이 소비자에게 메시지를 자동으로 다시 보내겠습니까?

아니요. 카프카 소비자는 클라이언트가 열려있는 동안 순차적으로 메시지를 읽습니다. Kafka는 개별 메시지 승인과 같은 정교한 승인 모드를 지원하지 않으며 지정된 소비자 그룹 및 파티션 주제에 대한 오프셋 만 업데이트합니다. Spring Cloud Stream은 비동기 적으로 처리되어 (따라서 메시지 손실을 방지하는) 시나리오에서 Spring Cloud Stream의 메시지에 대한 수동 승인을 지원하지만, 일단 메시지가 수동으로 확인되면 오프셋이 저장되므로 동일한 메시지의 이전 메시지 파티션 - 토픽은 '읽기'로 간주됩니다. 실패한 메시지를 하나씩 출력하려면 DLQ 지원을 사용하고 후속 소비자에게 메시지를 수신하게하십시오. 소비자를 다시 시작하면 마지막으로 저장된 오프셋에서 다시 읽으므로 일련의 성공적으로 처리되지 않은 메시지에 대한 오프셋을 저장하지 않을 수 있습니다.

봄 클라우드 스트림 소비자가 내장되어 다시 시도하고 DLQ 지원 - http://docs.spring.io/spring-cloud-stream/docs/Brooklyn.SR2/reference/htmlsingle/#_kafka_consumer_properties뿐만 아니라 재시도 설정에서 enableDlq 기본 소비자 특성의 일부로 제공 참조 : http://docs.spring.io/spring-cloud-stream/docs/Brooklyn.SR2/reference/htmlsingle/#_consumer_properties