Kafka Producer와 Consumer 실전 사용법 – 메시지 발행과 수신 구조 완벽 이해
Apache Kafka의 핵심은 바로 Producer(생산자)와 Consumer(소비자)입니다. Producer는 메시지를 Kafka에 발행하고, Consumer는 이를 구독하여 처리합니다. 이 글에서는 Kafka의 Producer/Consumer 구조, 설정법, Java 코드 예제를 통해 실무에서 바로 쓸 수 있도록 정리합니다.
1. Kafka 구성 복습
Kafka 시스템은 다음과 같은 구조로 동작합니다:
[Producer] → [Kafka Broker] → [Consumer Group]
- Producer: 메시지를 특정 Topic에 발행
- Consumer: Topic을 구독하고 메시지를 처리
- Broker: Kafka 서버 (메시지 저장소)
2. Kafka 환경 준비 (로컬)
Docker를 사용한 간단한 Kafka 실행 예:
docker run -d --name zookeeper -p 2181:2181 bitnami/zookeeper
docker run -d --name kafka -p 9092:9092 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 \
-e ALLOW_PLAINTEXT_LISTENER=yes \
--link zookeeper bitnami/kafka
3. Kafka Producer 구현 (Java)
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("my-topic", "key1", "Hello Kafka!"));
producer.close();
포인트:
- key는 파티션 분배에 사용됨 (없어도 무관)
- value는 실제 메시지 내용
4. Kafka Consumer 구현 (Java)
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "my-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("my-topic"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s%n",
record.offset(), record.key(), record.value());
}
}
주의사항:
- Consumer Group ID가 다르면 메시지를 중복 처리할 수 있음
- poll 주기는 너무 길면 타임아웃 발생
5. Consumer Group이란?
동일한 Group ID를 가진 Consumer 들은 하나의 그룹으로 묶입니다. Kafka는 메시지를 같은 그룹 안의 Consumer에만 1번씩 분산 전송합니다.
예:
Consumer A (group: G1) → Partition 0
Consumer B (group: G1) → Partition 1
Consumer C (group: G2) → Partition 0, 1 모두 수신 (중복 수신 가능)
6. 실무 적용 팁
- 멀티 스레드로 처리 시, 각 Consumer는 독립된 스레드로 실행
- 메시지 유실 방지: ACK, Commit offset 직접 설정 가능
- Spring Kafka를 사용하면 더욱 간편한 구현 가능
7. 결론
Kafka Producer와 Consumer는 Kafka의 핵심 구성 요소입니다. Producer를 통해 실시간 데이터를 발행하고, Consumer를 통해 안정적으로 데이터를 수신 및 처리할 수 있습니다. Java 기반으로 직접 구현하거나 Spring Kafka를 활용해 생산성과 유지보수성을 향상시킬 수 있습니다.