백엔드 로직에 최적화가 필요해서 메시지 큐를 써야할 것 같은 상황에, Kafka를 쓰면 어떨까해서 고민해보다가 시간이 생겨 구현을 해보았습니다!
쉽게 구현이 될줄 알았는데, 생각보다 카프카 쪽 설정이 신경쓸 것들이 많더라구요.
1. 구성환경
배포를 같은 환경에서 자유롭게 진행하고자 카프카 컨테이너를 도커 안에 배치하도록 구성환경을 짰습니다.
모든 환경이 저랑 같을 수는 없겠지만, 저는 이런 시퀀스 구조로 카프카를 사용하도록 했어요.
1) 웹 사용자가 요청하면 Next.js 서버 사이드 단에서 Kafkajs를 호출
2) kafkajs는 도커 컨테이너에 있는 kafka broker에 publish
3) 같은 도커 컨테이너에 있는 Express.js에서 kafka를 subcribe하고 있는 상황에서 퍼블리싱이 일어나면 Express.js에서 정의한 이벤트 발생(Hello, Kafka! 텍스트 호출)
와 같이 물 흐르듯이 되었어야했는데, 그림과 같이 로컬환경에 있는 next.js에서 도커 컨테이너의 kafka 브로커까지 접속이 안되는 이슈가 있더라구요... 삽질을 많이 했습니다.
2. kafka docker-compose
아래는 카프카를 동작시킬 수 있는 docker-compose의 코드 입니다.
# docker-compose.yml
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
hostname: zookeeper
container_name: zookeeper
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka:latest
hostname: kafka
container_name: kafka
ports:
- "9093:9093"
environment:
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:9092, PLAINTEXT_HOST://localhost:9093 #INTERNAL에 kafka:9092는 고정
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT #내부:PLAINTEXT 외부:PLAINTEXT_HOST
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 # Replication factor: 3 larger than available brokers: 1 에러 발생 방지
depends_on:
- zookeeper
kafka쪽 environment를 보면 구성 설정이 많이 있는데, 이것들을 일단 그대로 써보시는 것을 추천합니다.
여기서 주의할 점이 SECURITY_PROTOCOL_MAP 부분이 있는데, 이 뒤에 있는 변수들은 제가 임의로 지정한 변수가 아니고 kafka에서 지정한 변수더라구요...
INTERNAL: (내부용인것 같음)
PLAINTEXT: (평문이라는 의미)
PLAINTEXT_HOST: (평문 호스트 라는 의미같은데... 일단 그대로 씁시다)
이 3개의 변수는 변경하지 마시고 그대로 가져다 쓰시면서 어떤 의미인지 확인해 보시면 좋을 것 같습니다.
컨테이너에 사용되는 이미지는 confluentinc/cp-kafka:latest 이것을 사용했는데, 다른 것보다는 이 이미지가 사용하기가 편하더라구요. 밑에서 설명할 GUI하고 연동도 됩니다!
3. UI for Apache Kafka
위 사진과 같이 현재 카프카 클러스터의 상태를 보여주는 GUI인데, docker-compose에 추가해서 kafka와 같이 사용하면 편리하더라구요. 현재 토픽 상태나 브로커 상태에 대해 한 눈에 알아보기 쉽게 되어 있습니다.
위의 docker-compose.yml 파일에 아래 kafka-ui 컨테이너를 추가해주시면 됩니다.
...
kafka-ui:
image: provectuslabs/kafka-ui
container_name: kafka-ui
ports:
- "8090:8080" # 8080은 많이들 사용하니 8090으로 접속하시길
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=local # 임의의 이름 아무렇게나 지으셔도 됩니다
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:9092
- KAFKA_CLUSTERS_0_ZOOKEEPER=zookeeper:2181
...
관련 링크는 여기입니다.
https://docs.kafka-ui.provectus.io/
4. 실행결과
위와 같이 컨슈머에서 등록한 이벤트를 발생시킬 수 있는 것을 확인했습니다.
'Backend&Devops > Docker' 카테고리의 다른 글
[리눅스] docker, docker-compose 설치 (0) | 2024.02.21 |
---|---|
[Docker] 도커 안에 젠킨스 설치 (도커 인 도커, Docker In Docker, D in D) (0) | 2022.05.06 |
[Docker] Docker Compose 문법 정리 (0) | 2021.12.23 |
[Dockerfile] Dockerfile express 연동하기 (0) | 2021.12.21 |
[Dockerfile] Dockerfile이란? Dockerfile 옵션 (1) | 2021.12.21 |