본문 바로가기
Spring/Cloud

Spring With Kafka

by 진꿈청 2024. 5. 5.

이번 캡스톤 디자인 프로젝트를 진행하며 MSA를 사용하게 되었다.

 

이에 따라 서비스들을 잘게 나누었고 서비스들간의 비동기 이벤트를 처리하기 위해

 

Kafka를 사용하게 되었다. 본 포스팅에는 주키퍼/카프카는 무엇인지 어떻게 사용하는지 알아보도록 하자.

 

자세한 주키퍼/카프카의 내용은 다른 포스팅으로 다뤄 보도록 하겠다.

 

우선, Kafka를 알아보기 이전 Zookeeper에 관해 알아보도록 하자.

 

(카프카의 여러 버전 중 주키퍼 없이 독립적으로 작동하는 카프카도 존재하지만,

통상적으로 주키퍼와 함께 클러스터를 구축하여 동작하기에 주키퍼가 뭔지 알아보도록 한다.)

 

Apache Zookeeper

Apache Zookeeper

주키퍼는 이름처럼 동물원 사육사이다. 왜 이름이 이럴까?

 

많은 오픈 소스 프로젝트를 지원하는 Apache 재단의 프로젝트 이름은

자연재해 & 동물과 관련된 이름이다.

  • 아파치 카프카(까마귀)
  • 아파치 하둡(코끼리)
  • 아파치 스파크
  • 아파치 스톰
  • 아파치 타조

그래서 이런 아파치 재단의 프로젝트들을 위한 분산 코디네이션 서비스를 지원하는 것이 주키퍼이기에

주키퍼의 이름이 만들어지게 된 것이다.

 

간단 요약하자면 아래와 같다.

 

Apache Zookeeper란?

  • 분산 코디네이션 서비스를 제공하는 오픈소스 프로젝트
  • 개발자가 코디네이션 로직보다는 비즈니스 핵심 로직에 집중할 수 있도록 지원
  • Zookeeper는 Leader-Follow로 구성되는 Master-Slave 아키텍처 기반
  • 고가용성을 보장하며 개별 시스템을 관리 및 조율

 

그럼 왜 주키퍼가 탄생하게 되었을까?

 

1. 대규모 시스템

  • 현재 빅데이터와 클라우드 환경에서 대규모 시스템들이 동작
  • 대규모 시스템은 수많은 서버와 인프라로 구성
  • 따라서, 이런 개별적인 시스템들을 각각 조율해야 하는 코디네이션 시스템의 수요 발생

2. 코디네이션 시스템

  • 분산된 어플리케이션이 제대로 조율되지 못하면 클러스터 공유 자원간의 경쟁상태 발생
  • 코디네이션 시스템은 분산 시스템 내에 중요한 상태 정보나 설정 정보등을 유지
  • 코디네이션 시스템의 장애는 전체 시스템의 장애를 유발

 

이제 주키퍼의 탄생 이유와 어떤 용도인지 알게 되었을 것이다.

아래 주키퍼 구성은 간단하게만 알고만 넘어가자.

 

 

Apache Zookeeper 구성

  • Ensemble(앙상블): Leader-Follower을 기반으로 여러 Zookeeper 서버로 이루어짐
  • Quorum(쿼럼): 앙상블 데이터의 불일치를 방지(주로 과반수 커럼 사용)
  • Zookeeper 데이터 모델: 분산 데이터 시스템인 znode로 이루어진 Zookeeper 데이터 모델

 

 

Apache Zookeeper 제공 기능

  • Configuration Management(설정 관리)
    • 클러스터의 설정 정보를 최신으로 유지
    • 조율 시스템으로 사용
  • Cluster Management(클러스터 관리)
    • 클러스터의 서버가 추가되거나 제외될 때
    • 그 정보를 클러스터 안 서버들이 공유하는 데 사용
  • Leader Selection(리더 채택)
    • 다중 어플리케이션 중에서 어떤 노드를 리더로 선출할 지를 정하는 로직을 만드는데 사용
    • 주로 복제된 여러 노드 . 중연산이 이루어지는 하나의 노드를 택하는 . 데사용
  • Locking and synchronization service(락, 동기화 서비스)
    • 클러스터에 쓰기 연산이 빈번할 경우 경쟁 상태에 들어갈 가능성이 커짐
    • 이는 데이터 불일치를 발생하므로 락, 동기화 서비스를 이용하여 사전에 방지

 

여기까지 간단하게 주키퍼가 무엇인지 알아보았다. 주키퍼의 실제 클러스터 구축은 나중에 기회가 된다면 포스팅으로 다루도록 하겠다.

 

드디어 카프카를 알아보자.

 

Apache Kafka

아파치 카프카란 무엇일까?

 

우선, Kafka는 링크드인 웹사이트에서 생성되는 로그를 통한 활동 추적을 목적으로 개발되었다.

하지만, 시간이 지날수록 데이터 전송 라인이 복잡해지고 아키텍처가 거대해졌다.

 

당시 링크드인의 시스템 요구 사항은 다음과 같았다고 한다.

  • 높은 처리량으로 실시간 처리
  • 임의의 타이밍에서 데이터를 읽음
  • 다양한 제품과 시스템에 쉽게 연동
  • 메시지를 잃지 않음

그래서 위의 요구 사항을 충족할 수 있는 시스템 개발이 필요해졌고 이와 함께 만들어진 것이 카프카이다.

 

마찬가지로, 간단 요약하자면 카프카

 

Apache Kafka

 

  • 여러 대의 분산 서버에서 대량의 데이터를 처리하는 분산 메시징 시스템
  • 메시지(데이터)를 받고, 받은 메시지를 다른 시스템이나 장치에 보내기 위해 사용
  • 카프카느 여러 시스템과 장치를 연결하는 중요한 역할을 수행
  • 대량의 데이터를 높은 처리량과 실시간으로 취급하기 위한 제품

 

 

그렇다면 카프카의 특징은 무엇일까?

 

높은 처리량

  • 많은 양의 데이터를 묶음 단위로 처리하여 빠르게 처리 가능
  • 동일 목적의 데이터를 여러 파티션에 분배 후 병렬 처리 가능

영속성

  • 전송 받은 데이터를 메모리가 아닌 파일 시스템에 저장
  • 파일 I/O 성능 향상을 위한 페이지 캐시 영역을 메모리에 따로 생성하여 사용
  • 디스크 기반의 파일 시스템을 활용하여 서비스에 장애가 생기더라도 재시작하여 안전하게 데이터 재처리

확장성

  • 가변적인 환경에서 안정적으로 확장 가능

고가용성

  • 일부 서버에 장애가 생겨도 무중단으로 안전하고 지속적으로 데이터 처리 가능
  • 전송 받은 데이터를 하나의 Broker에만 저장하는 것이 아닌 여러 Broker에 복제하여 저장

 

이 밖의 Ack등을 활용한 전달 보증 기능을 제공하는 등 많은 특징을 가지고 있다.

 

 

카프카의 구성 요소

 

Broker

  • 데이터를 수신 및 전달하는 서비스
  • 브로커 안에 토픽, 토픽 안에 파티션

Message

  • 카프카에서 다루는 데이터의 최소 단위
  • 메시지는 Key와 Value를 갖게 되며 이는 파티셔닝에 이용

Producer

  • 데이터의 생산자
  • 브로커에 메시지를 보내는 애플리케이션

Consumer

  • 브로커에서 메시지를 취득
  • Current Offset으로부터 브로커의 최신 메시지까지 취득

Topic

  • 메시지를 토픽별로 관리하는 스토리지
  • 브로커에 배치되어 관리

위에서 설명한 카프카 구성 요소 각각에도 엄청나게 많은 개념들이 많다.

(컨슈머 그룹, 파티션, 파티셔닝, 리더-팔로우 파티션, 레플리카(복제) 등)

 

마찬가지로 위 내용은 Spring With Kafka의 범위 내에서 다루기에는 글이 너무 길어지므로 다음에 다루도록 하겠다,

 

 

Apache Kafka 참고 개념

 

Zookeeper

  • 카프카의 브로커 분산 처리 도구로 아파치 주키퍼 필요
  • Topic과 Partition을 관리하기 위한 구성 요소(Leader-Follower)

Kafka Client

  • 토픽 작성 등 카프카의 동작 및 운영 상에 필요한 조작을 위한 서버
  • 메시지의 송수신을 처리하는 서버 X

Kafka Cluster

  • 카프카는 여러 대의 브로커 서버, 주키퍼 서버들로 이루어짐
  • 카프카 클러스터
    • 브로커, 주키퍼에 의해 구성된 클러스터 시스템

 

자.. 여기까지 길고 긴 아파치 주키퍼와 아파치 카프카에 대한 개요를 알아보았다.

 

 

그럼 이제 본격적으로 스프링에서 비동기 이벤트 처리를 위해 카프카를 사용해보자.

 

 

Spring With Kafka

 

필자는 도커를 활용해 카프카를 사용했다.

 

카프카는 공식 이미지가 없기 때문에 가장 많은 스타를 갖고 있는

 

wurstmeister 이미지를 사용할 것이다.

 

또한, 카프카를 주키퍼와 함께 사용하기 위해 다음과 같이 도커 컴포즈 yaml을 작성해준다.

 

 

docker-compose.yml

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka:latest
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

 

간략하게 설명하자면 주키퍼의 포트는 주키퍼의 기본 포트인 2181 포트로 사용을 하고

카프카는 해당 주키퍼에 단일 노드로만 접근한다.

 

원한다면 여러 카프카 컨테이너를 구동하여 카프카 클러스터를 구축하는 것도 가능하다.

 

이 글을 처음부터 읽은 사람이라면 이 부분에서 의아해 할 수도 있다.

 

 

카프카는 클러스터 구축이 가능하고 만약 단일 노드를 사용하면 장애시 큰 문제가 발생하는 것 아닌가?

 

맞다.

 

하물며 파티션도 하나만 사용하고 이에 따라 당연하게도 레플리카도 1개이다.

 

그럼에도 이렇게 사용하는 이유는 카프카는 앞서 설명한 것처럼 굉장히 높은 처리량을 갖고 있기에,

내가 캡스톤 프로젝트로 진행하는 프로젝트에서 단일 노드면 충분하다.

 

또한, 카프카는 내부에서 여러 방법의 파티셔닝을 지원한다. 그렇기에 파티션을 여러 개로 나눠버리면

이벤트 순서가 중요한 우리 캡스톤 프로젝트에서 문제가 될 수 있다.

 

그렇기에 단일 노드만 사용하기로 하였다.

 

 

자, 이제 실제로 구동되었는지 docker ps를 통해 알아보자.

 

 

잘 구동되었다.

 

당연하게도 이제는 스프링에서 카프카에 접근하기 위해 build.gradle, application.yml에 관련 내용을 추가해주어야 한다.

 

build.gradle

/* kafka */
implementation 'org.springframework.kafka:spring-kafka'
testImplementation 'org.springframework.kafka:spring-kafka-test'

 

application.yml

spring:
  devtools:
    livereload:
      enabled: false
  kafka:
    bootstrap-servers: localhost:9092
    topic:
      community-server-event: "communityServerEventTopic"
      community-dm-event: "communityDmEventTopic"
      community-channel-event: "communityChannelEventTopic"
      community-category-event: "communityCategoryEventTopic"
      community-forum-event: "communityForumEventTopic"

 

본래, 카프카의 컨슈머를 사용하면 컨슈머 그룹 설정 등 다양한 설정이 필요하다.

(필자의 서비스는 다른 서비스에 비동기 이벤트 전송만을 하기에 위와 같이만 설정하였다.(Producer만 작업))

 

중요한점은 bootstrap-servers: localhost:9092 이다. 

 

앞서, docker-compose.yml에서 아래와 같이 설정하였기에 저렇게 설정해둔 것이다.

KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1

 

만약, 주소를 다르게 하였다면 잘 맞춰서 설정해주어야 한다.(실제 배포 등에서 유의하여 작성하자)

 

 

 

Kafka Topic 생성

현재는 당연하게도 카프카의 토픽 생성이 되어있지 않다.

 

스프링을 사용하여 카프카 컨테이너에 직접 접근하지 않아도 KafkaAdmin 클래스를 사용하여 토픽을 생성하는 것이 가능하다.

만약 이미 존재하는 토픽이라면 추가로 생성하지 않는다.

 

KafkaTopicConfig

@Configuration
public class KafkaTopicConfig {
    
    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapAddress;

    @Value("${spring.kafka.topic.community-server-event}")
    private String communityServerEventTopic;

    @Value("${spring.kafka.topic.community-dm-event}")
    private String communityDmEventTopic;

    @Value("${spring.kafka.topic.community-channel-event}")
    private String communityChannelEventTopic;

    @Value("${spring.kafka.topic.community-category-event}")
    private String communityCategoryEventTopic;

    @Value("${spring.kafka.topic.community-forum-event}")
    private String communityForumEventTopic;

    @Bean
    public KafkaAdmin kafkaAdmin(){
        Map<String, Object> configurations = new HashMap<>();
        configurations.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
        return new KafkaAdmin(configurations);
    }

    @Bean
    public NewTopic communityServerEventTopic() {
        return TopicBuilder.name(communityServerEventTopic)
                .partitions(1)
                .replicas(1)
                .build();
    }

    @Bean
    public NewTopic communityDmEventTopic() {
        return TopicBuilder.name(communityDmEventTopic)
                .partitions(1)
                .replicas(1)
                .build();
    }

    @Bean
    public NewTopic communityChannelEventTopic() {
        return TopicBuilder.name(communityChannelEventTopic)
                .partitions(1)
                .replicas(1)
                .build();
    }

    @Bean
    public NewTopic communityCategoryEventTopic() {
        return TopicBuilder.name(communityCategoryEventTopic)
                .partitions(1)
                .replicas(1)
                .build();
    }

 

코드를 살펴보면 kafkaAdmin 메소드에서 앞서 말한 카프카 어드민을 빈으로 등록한다.

이로써 우리는 토픽 생성이 가능해진다.

 

그 후, NewTopic 클래스로 새로운 토픽을 파티션 1개, 레플리카 1개로 생성한다.
이때, application.yml로 설정한 이벤트 토픽 이름들을 사용한다.

 

만약, 토픽이 잘 설정됐는지 확인하고 싶다면 다음과 같은 방법을 따르면 된다.

 

  1. docker ps 명령어로 컨테이너 ID 확인
  2. docker exec -it 컨테이너ID bash
  3. cd /opt/kafka/bin
  4. kafka-topic.sh --list --bootstrap-server localhost:9092

 

잘 생성되었다.

 

 

이제 토픽을 생성했으니 해당 토픽으로 비동기 이벤트 처리를 위한 Producer를 구성해보자.

 

KafkaProducerConfig

@EnableKafka
@Configuration
public class KafkaProducerConfig {

    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;

    @Bean
    public Map<String, Object> producerConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put(org.apache.kafka.clients.producer.ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        config.put(org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
                StringSerializer.class);
        config.put(org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
                JsonSerializer.class);

        return config;
    }

    @Bean
    public ProducerFactory<String, CommunityServerEventDto> communityServerEventProducerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfig());
    }

    @Bean
    public KafkaTemplate<String, CommunityServerEventDto> communityServerEventKafkaTemplate() {
        return new KafkaTemplate<>(communityServerEventProducerFactory());
    }

    @Bean
    public ProducerFactory<String, CommunityDmEventDto> communityDmEventProducerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfig());
    }

    @Bean
    public KafkaTemplate<String, CommunityDmEventDto> communityDmEventKafkaTemplate() {
        return new KafkaTemplate<>(communityDmEventProducerFactory());
    }

    @Bean
    public ProducerFactory<String, CommunityChannelEventDto> communityChannelEventProducerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfig());
    }

    @Bean
    public KafkaTemplate<String, CommunityChannelEventDto> communityChannelEventKafkaTemplate() {
        return new KafkaTemplate<>(communityChannelEventProducerFactory());
    }

    @Bean
    public ProducerFactory<String, CommunityCategoryEventDto> communityCategoryEventProducerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfig());
    }

    @Bean
    public KafkaTemplate<String, CommunityCategoryEventDto> communityCategoryEventKafkaTemplate() {
        return new KafkaTemplate<>(communityCategoryEventProducerFactory());
    }
}
  • producerConfig
    • 말 그대로 프로듀서 환경설정이다.(config으로 등록)
    • application.yml에서 정의한 부트스트랩 서버 주소로 이벤트(메시지)를 전송한다.
    • 이때, 직렬화를 하여 전송하는데 key값에 대해선 String 직렬화를 사용하며,
      value 값에 대해선 Json 직렬화를 하도록 설정한다. 
  • ProducerFactory<{key 타입}, {value 클래스}>
    • ProducerFactory 인터페이스를 활용하여 사용할 key : value -> {String} : {value 클래스}를
      Producer Factory 형식의 으로 등록한다.
    • 이때, 필자는 토픽별로 ProducerFactory를 생성하였다.
  • KafkaTemplate<{key 타입}, {value 클래스}>
    • 이벤트(메시지)를 실제로 전송할 주체가 되는 KafkaTemplate 클래스를 <key, value>에 맞는 클래스로 생성한다.
    • 또한, 실제 서비스에서도 사용하기 위해 으로 등록한다.
    • 마찬가지로, 필자는 토픽별로 KafkaTemplate를 생성하였다.

 

자, 이제는 실제 서비스 클래스에서 사용해보자.

 

ServerCommandService

@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class ServerCommandService {

    ...
    
    private static final String serverKafkaTopic = "communityServerEventTopic";

    ...
    private final KafkaTemplate<String, CommunityServerEventDto> serverKafkaTemplate;

    ...

    public ServerResponseDto update(ServerUpdateRequestDto requestDto, MultipartFile file) {
        ...

        serverKafkaTemplate.send(serverKafkaTopic, CommunityServerEventDto.of("server-update", findServer));

        printKafkaLog("update");

        ...
    }

    ...

    private void printKafkaLog(String type) {
        log.info("Kafka event send about Server {}", type);
    }
}

 

우선, 전송할 토픽명을 전역 변수로 등록한다.(communityServerEventTopic)

 

그 후, 실제로 이벤트(메시지)를 전송할 빈으로 등록된 KafkaTemplate 클래스를 선언한다.

 

다음으로, 사용될 메서드에서 KafkaTemplate, 토픽 이름, value 클래스와 함께 전송한다.

 

필자는 printKafkaLog 메서드를 만들어 카프카 메시지 전송시 로그가 출력되도록 하였다.

 

이렇게 프로듀서를 통해 전송한 메시지는 해당 토픽을 구독하는 컨슈머 그룹(컨슈머)에게 전달된다.

이를 통해 우리는 비동기 이벤트를 처리하게 된다.

 

마찬가지로, 우리는 도커 컨테이너에 접속하여 실제 메시지가 전송이 잘 되는지 확인이 가능하다.

 

 

 

 

우리는 메시지가 전달되었는지 확인을 위해 도커 컨테이너에 접속하여 확인했지만,

실제로는 해당 이벤트를 처리하는 토픽을 구독한 서비스에 의해 특정 작업이 수행될 것이다.

 

만약, 그렇다면 해당 서비스는 컨슈머 그룹(컨슈머) 관련 설정이 필요할 것이다.

 

 

이렇게 주키퍼, 카프카의 개요를 거처 Spring에서 카프카를 사용하는 방법에 대해 알아보았다.

 

 

마치며

본 포스팅에서는 주키퍼, 카프카의 개념 정도만 알아보았다. 실제로는 정말 많은 기능과 설정들이 존재한다.

스프링에서 해당 설정등을 직접 만질 수도 있다. (레플리카, 파티션 개수 등)

 

실제로 카프카 메시지 전송시 스프링 서버의 로그에는 다음과 같은 내용이 출력된다.

 

2024-05-04T19:08:47.089+09:00  INFO 6192 --- [nio-8080-exec-2] o.a.k.clients.producer.ProducerConfig    : ProducerConfig values: 
	acks = -1
	auto.include.jmx.reporter = true
	batch.size = 16384
	bootstrap.servers = [localhost:9092]
	buffer.memory = 33554432
	client.dns.lookup = use_all_dns_ips
	client.id = producer-2
	compression.type = none
	connections.max.idle.ms = 540000
	delivery.timeout.ms = 120000
	enable.idempotence = true
	interceptor.classes = []
	key.serializer = class org.apache.kafka.common.serialization.StringSerializer
	linger.ms = 0
	max.block.ms = 60000
	max.in.flight.requests.per.connection = 5
	max.request.size = 1048576
	metadata.max.age.ms = 300000
	metadata.max.idle.ms = 300000
	metric.reporters = []
	metrics.num.samples = 2
	metrics.recording.level = INFO
	metrics.sample.window.ms = 30000
	partitioner.adaptive.partitioning.enable = true
	partitioner.availability.timeout.ms = 0
	partitioner.class = null
	partitioner.ignore.keys = false
	receive.buffer.bytes = 32768
	reconnect.backoff.max.ms = 1000
	reconnect.backoff.ms = 50
	request.timeout.ms = 30000
	retries = 2147483647
	retry.backoff.ms = 100
	sasl.client.callback.handler.class = null
	sasl.jaas.config = null
	sasl.kerberos.kinit.cmd = /usr/bin/kinit
	sasl.kerberos.min.time.before.relogin = 60000
	sasl.kerberos.service.name = null
	sasl.kerberos.ticket.renew.jitter = 0.05
	sasl.kerberos.ticket.renew.window.factor = 0.8
	sasl.login.callback.handler.class = null
	sasl.login.class = null
	sasl.login.connect.timeout.ms = null
	sasl.login.read.timeout.ms = null
	sasl.login.refresh.buffer.seconds = 300
	sasl.login.refresh.min.period.seconds = 60
	sasl.login.refresh.window.factor = 0.8
	sasl.login.refresh.window.jitter = 0.05
	sasl.login.retry.backoff.max.ms = 10000
	sasl.login.retry.backoff.ms = 100
	sasl.mechanism = GSSAPI
	sasl.oauthbearer.clock.skew.seconds = 30
	sasl.oauthbearer.expected.audience = null
	sasl.oauthbearer.expected.issuer = null
	sasl.oauthbearer.jwks.endpoint.refresh.ms = 3600000
	sasl.oauthbearer.jwks.endpoint.retry.backoff.max.ms = 10000
	sasl.oauthbearer.jwks.endpoint.retry.backoff.ms = 100
	sasl.oauthbearer.jwks.endpoint.url = null
	sasl.oauthbearer.scope.claim.name = scope
	sasl.oauthbearer.sub.claim.name = sub
	sasl.oauthbearer.token.endpoint.url = null
	security.protocol = PLAINTEXT
	security.providers = null
	send.buffer.bytes = 131072
	socket.connection.setup.timeout.max.ms = 30000
	socket.connection.setup.timeout.ms = 10000
	ssl.cipher.suites = null
	ssl.enabled.protocols = [TLSv1.2, TLSv1.3]
	ssl.endpoint.identification.algorithm = https
	ssl.engine.factory.class = null
	ssl.key.password = null
	ssl.keymanager.algorithm = SunX509
	ssl.keystore.certificate.chain = null
	ssl.keystore.key = null
	ssl.keystore.location = null
	ssl.keystore.password = null
	ssl.keystore.type = JKS
	ssl.protocol = TLSv1.3
	ssl.provider = null
	ssl.secure.random.implementation = null
	ssl.trustmanager.algorithm = PKIX
	ssl.truststore.certificates = null
	ssl.truststore.location = null
	ssl.truststore.password = null
	ssl.truststore.type = JKS
	transaction.timeout.ms = 60000
	transactional.id = null
	value.serializer = class org.springframework.kafka.support.serializer.JsonSerializer

 

이것만 보더라도 내부에서 수많은 작업이 일어난다는 것을 확인할 수 있다.

 

기회가 된다면 아는 범위 내에서 주키퍼, 카프카의 세부 개념을 포스팅으로 다뤄보도록 하고,

직접 주키퍼, 카프카를 활용하여 클러스터를 구축해보는 포스팅도 다뤄보겠다.

 

 

캡스톤 디자인 프로젝트 안에서 MSA, Spring Cloud, Kafka 등 많은 것을 접목하게 되어 어려운 부분도 있지만,

재밌는 부분도 많은 것 같다.

 

'Spring > Cloud' 카테고리의 다른 글

[Spring Cloud] Spring에서 MSA를 구축해보자  (1) 2024.03.27
Spring Cloud란?  (0) 2024.03.07
Cloud Native, 12 factors, MSA  (2) 2024.03.07