Advanced Spring Boot 4: Event-Driven Architecture (Kafka) · 강의

멱등성 프로듀서와 컨슈머

메시지를 다시 처리하는 상황에서도 일관된 상태를 보장하도록 멱등성 프로듀서와 컨슈머를 설계하는 것이 왜 중요한지 익힙니다.

레슨 2/411개 단계

멱등성 프로듀서와 컨슈머은(는) CoddyKit의 무료 Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

What is Idempotence?

Imagine pressing a light switch. If you press it once, the light turns on. If you press it again, the light stays on – it doesn't get 'more on'. This is idempotence!

An operation is idempotent if performing it multiple times produces the same result as performing it once. It's about the final state, not how many times you tried to get there.

Why Idempotence in Messaging?

In distributed systems like those using Kafka, messages can sometimes be delivered more than once. This can happen due to network issues, consumer crashes, or rebalances.

If your application isn't designed to handle these duplicates, reprocessing the same message multiple times could lead to incorrect data or undesirable side effects.

Kafka's Idempotent Producers

Good news! Kafka provides built-in support for idempotent producers. This means when you send a message, Kafka guarantees that it will be written to the topic log exactly once, even if the producer retries sending it due to transient failures.

This prevents duplicate messages from being stored in Kafka itself.

How Kafka Idempotence Works

Kafka achieves producer idempotence by assigning a unique Producer ID (PID) to each producer session and a monotonically increasing sequence number to each message batch sent by that producer.

Kafka brokers use these IDs and sequence numbers to detect and discard any duplicate message batches before they are written to the log.

Enabling Idempotent Producers

In Spring Boot, enabling an idempotent Kafka producer is straightforward. You just need to set a specific property in your application.properties or application.yml.

  • spring.kafka.producer.properties.enable.idempotence=true

Setting this property also implicitly configures other necessary producer settings, such as acks=all and retries.

Idempotent Producer Example

Try running this simple Spring Boot application. It sends a message to a Kafka topic with idempotence enabled. Notice the configuration comments.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import java.util.UUID;

@SpringBootApplication
public class IdempotentProducerApp {

  public static void main(String[] args) {
    SpringApplication.run(IdempotentProducerApp.class, args);
  }

  @Bean
  public CommandLineRunner runner(
    KafkaTemplate<String, String> kafkaTemplate) {
    return args -> {
      String messageKey = UUID.randomUUID().toString();
      String messageValue = "Hello from Idempotent Producer!";
      System.out.println("Sending message with key: " 
                         + messageKey);
      kafkaTemplate.send("my-idempotent-topic", 
                         messageKey, messageValue)
        .addCallback(
          result -> System.out.println(
            "Message sent successfully!"),
          ex -> System.err.println(
            "Failed to send: " + ex.getMessage())
        );
    };
  }
}
// Add to application.properties:
// spring.kafka.producer.bootstrap-servers=localhost:9092
// spring.kafka.producer.key-serializer=
//   org.apache.kafka.common.serialization.StringSerializer
// spring.kafka.producer.value-serializer=
//   org.apache.kafka.common.serialization.StringSerializer
// spring.kafka.producer.properties.enable.idempotence=true

Idempotent Consumers

While Kafka helps producers avoid sending duplicates to the log, it doesn't guarantee that consumers will process messages exactly once. Consumers might read the same message multiple times.

Therefore, idempotent consumer logic is crucial. This means your application code must ensure that processing a message multiple times has no unintended side effects on your system's state.

Strategies for Idempotent Consumers

Here are common approaches to make your consumers idempotent:

  • Unique ID Tracking: Store a unique identifier (like Kafka's topic-partition-offset or a business ID from the message) in a persistent store. Check this store before processing.
  • State Comparison: Before applying an update, compare the incoming message's data with the current state in your system. Only apply if the state needs changing.
  • Business Idempotence: Design your business operations to be naturally idempotent. For example, 'set user status to X' is idempotent, 'increment user balance by Y' is not.

Consumer Idempotence Example

This Spring Boot example demonstrates a basic idempotent consumer using a set to track processed records. In a real application, this would be a persistent store like a database or Redis.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import java.util.HashSet;
import java.util.Set;

@SpringBootApplication
public class IdempotentConsumerApp {

  public static void main(String[] args) {
    SpringApplication.run(IdempotentConsumerApp.class, args);
  }

  @Component
  public static class MyKafkaListener {
    // In a real app, this would be a persistent store (DB, Redis)
    private final Set<String> processedRecordIds = new HashSet<>();

    @KafkaListener(topics = "my-idempotent-topic", 
                   groupId = "idempotent-group")
    public void listen(ConsumerRecord<String, String> record) {
      // Unique ID for the record (topic-partition-offset)
      String recordId = record.topic() + "-" + record.partition()
                        + "-" + record.offset();

      if (processedRecordIds.contains(recordId)) {
        System.out.println("Duplicate record received (ID: " 
                           + recordId + "). Skipping processing.");
        return;
      }

      // Simulate processing the message
      System.out.println("Processing record ID: " + recordId 
                         + ", Key: " + record.key() 
                         + ", Value: " + record.value());
      // Add to processed set AFTER successful processing
      processedRecordIds.add(recordId);

      // In a real scenario, processing might involve DB updates
      // and 'add' would happen as part of a transaction.
    }
  }
}
// Add to application.properties:
// spring.kafka.consumer.bootstrap-servers=localhost:9092
// spring.kafka.consumer.key-deserializer=
//   org.apache.kafka.common.serialization.StringDeserializer
// spring.kafka.consumer.value-deserializer=
//   org.apache.kafka.common.serialization.StringDeserializer
// spring.kafka.consumer.group-id=idempotent-group
// spring.kafka.consumer.auto-offset-reset=earliest

Quick Check: Idempotence

Test your understanding of idempotent operations in messaging.

Recap & Next Steps

Great job! In this lesson, you've learned about the vital concept of idempotence in event-driven systems.

  • You understand why idempotence is critical for maintaining consistent state when messages might be reprocessed.
  • You saw how Kafka's built-in idempotent producers prevent duplicate messages from entering the topic.
  • You explored strategies for building idempotent consumers, ensuring your application handles duplicate messages gracefully.

Mastering idempotence is a key step towards building robust and reliable Kafka applications!

무료로 시작

AI 튜터와 함께 Advanced Spring Boot 4: Event-Driven Architecture (Kafka)을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
12
레슨
48

자주 묻는 질문

“멱등성 프로듀서와 컨슈머” 강의는 무료인가요?

네 — “멱등성 프로듀서와 컨슈머” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의 전체를 잠금 해제할 수 있습니다. Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의에는 총 4개의 강의가 포함되어 있습니다.

“멱등성 프로듀서와 컨슈머”에서 뭘 배우나요?

메시지를 다시 처리하는 상황에서도 일관된 상태를 보장하도록 멱등성 프로듀서와 컨슈머를 설계하는 것이 왜 중요한지 익힙니다. 브라우저에서 직접 실행하는 실습 코드로 Advanced Spring Boot 4: Event-Driven Architecture (Kafka)을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Advanced Spring Boot 4: Event-Driven Architecture (Kafka)을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Advanced Spring Boot 4: Event-Driven Architecture (Kafka)은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“멱등성 프로듀서와 컨슈머” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Advanced Spring Boot 4: Event-Driven Architecture (Kafka) 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Kafka 성능 튜닝 팁
  2. 멱등성 프로듀서와 컨슈머
  3. Spring Boot Kafka 앱의 클라우드 배포
  4. 용량 계획: 파티션과 복제
← Advanced Spring Boot 4: Event-Driven Architecture (Kafka)(으)로 돌아가기