본문 바로가기

Study Information Technology

Spring Boot와 Kafka를 활용한 메시징 시스템 구축

728x90
반응형

Spring Boot와 Kafka를 활용한 메시징 시스템 구축

Overview

Spring Boot와 Apache Kafka는 현대의 마이크로서비스 아키텍처에서 데이터 전송과 비동기 처리를 위한 강력한 조합입니다. 이 두 기술을 함께 사용하면 확장성 있고 신뢰성이 높은 애플리케이션을 구축할 수 있습니다. 이 글에서는 Spring Boot 애플리케이션에서 Kafka를 설정하고 사용하는 방법을 자세히 설명하겠습니다. 예제 코드와 함께 Kafka의 기본 개념, 설정 방법, 에러 처리, 그리고 운영 중 발생할 수 있는 문제를 해결하는 방법을 다루겠습니다.

Kafka 기본 개념

Kafka는 고성능 분산 메시징 시스템으로, 다음과 같은 주요 구성 요소로 이루어져 있습니다:

  1. Producer: 메시지를 생성하여 Kafka에 전송하는 클라이언트입니다.
  2. Consumer: Kafka에서 메시지를 읽어오는 클라이언트입니다.
  3. Topic: 메시지가 전송되는 카테고리입니다. 각 Topic은 여러 Partition으로 나뉘어져 있습니다.
  4. Partition: Topic의 데이터 저장 단위로, 메시지의 순서를 보장합니다.
  5. Broker: Kafka 클러스터의 서버로, Topic과 Partition을 관리하고 메시지를 저장합니다.

Spring Boot에서 Kafka 설정하기

1. Maven 의존성 추가

Spring Boot 애플리케이션에서 Kafka를 사용하기 위해 spring-kafka 의존성을 추가합니다. pom.xml 파일에 아래 코드를 추가하세요.

<dependency>
  <groupId>org.springframework.kafka</groupId>
  <artifactId>spring-kafka</artifactId>
</dependency>

2. Kafka 설정 파일

application.yml 또는 application.properties 파일에 Kafka의 기본 설정을 추가합니다.

spring:
kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: my-group
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

3. Producer와 Consumer 클래스 생성

이제 Kafka Producer와 Consumer를 구현합니다.

Producer 구현

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
public class KafkaProducer {

@Autowired
private KafkaTemplate<String, String> kafkaTemplate;

public void sendMessage(String topic, String message) {
kafkaTemplate.send(topic, message);
System.out.println("메시지 전송: " + message);
}
}

Consumer 구현

import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;

@Service
public class KafkaConsumer {

@KafkaListener(topics = "my_topic", groupId = "my-group")
public void listen(String message) {
System.out.println("수신된 메시지: " + message);
}
}

4. Controller 구현

Producer를 호출하기 위해 간단한 REST API를 만드는 Controller를 작성합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {

@Autowired
private KafkaProducer kafkaProducer;

@PostMapping("/send")
public void sendMessage(@RequestBody String message) {
kafkaProducer.sendMessage("my_topic", message);
}
}

5. Kafka 서버 실행

Kafka를 사용하기 위해 로컬에서 Kafka 브로커를 실행해야 합니다. Kafka가 설치된 경로로 가서 아래 명령어로 Kafka를 시작합니다.

# Zookeeper 시작
bin/zookeeper-server-start.sh config/zookeeper.properties

# Kafka 브로커 시작
bin/kafka-server-start.sh config/server.properties

6. 테스트

이제 애플리케이션을 실행하고, Postman이나 curl을 이용하여 메시지를 전송해보세요.

curl -X POST http://localhost:8080/send -H "Content-Type: application/json" -d '"Hello Kafka!"'

Consumer는 이 메시지를 수신하여 콘솔에 출력합니다.

에러 처리 및 해결책

Kafka를 사용할 때 발생할 수 있는 여러 가지 오류가 있습니다. 다음은 일반적인 에러와 그 해결책입니다.

1. Connection Failure

오류 코드

org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.

해결책

  • Kafka 브로커가 실행되고 있는지 확인합니다.
  • bootstrap-servers 설정이 올바른지 점검합니다.

2. Serialization Error

오류 코드

org.apache.kafka.common.serialization.SerializationException: Can't deserialize data

해결책

  • Producer와 Consumer에서 동일한 직렬화기를 설정했는지 확인합니다. 위에서 제공한 코드처럼 둘 다 StringDeserializer를 사용해야 합니다.

3. Offset Out of Range

오류 코드

org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offset 15 is out of range

해결책

  • auto-offset-reset 속성을 earliest로 설정하여 가장 초기 메시지부터 읽도록 설정합니다.

운영 중 문제 해결

운영 중에는 다양한 문제가 발생할 수 있습니다. 여기서는 몇 가지 일반적인 상황을 다루겠습니다.

1. Consumer Lag

Consumer Lag는 Consumer가 처리하지 못한 메시지가 쌓이는 상황입니다. 이 경우 아래와 같은 조치를 취할 수 있습니다.

  • Consumer의 처리 성능을 개선합니다.
  • Consumer 그룹을 추가하여 여러 인스턴스가 메시지를 병렬로 처리하도록 합니다.

2. 데이터 중복

Kafka는 메시지의 순서를 보장하지만, 중복 메시지가 발생할 수 있습니다. 이를 방지하기 위해 idempotence를 사용하는 것이 좋습니다. Producer에서 다음과 같은 설정을 추가합니다.

spring:
kafka:
producer:
enable-idempotence: true

결론

Spring Boot와 Kafka를 이용한 메시징 시스템 구축은 마이크로서비스 아키텍처에서 비동기 처리를 구현하는 강력한 방법입니다. 위의 단계와 예제를 통해 기본적인 Producer와 Consumer를 설정하고, 발생할 수 있는 문제와 그 해결책을 이해했습니다. 이를 통해 안정적이고 확장 가능한 애플리케이션을 구축할 수 있을 것입니다.

참고문서

728x90
반응형