1. Introdução
Recentemente falamos sobre a arquitetura e funcionamento do Apache Kafka. Vimos também como executar uma instância de um cluster do Kafka localmente e realizamos alguns testes com o cli, você pode conferir mais neste artigo.
Hoje passo aqui para deixar uma dica rápida de como utilizar o Docker Compose para configurar um cluster do Kafka para testes localmente, e com o Kafka-ui iremos gerenciar nosso cluster pela interface web.
2. Pré-requisitos
Os pré-requisitos para replicar o que iremos abordar neste artigo são um computador Mac, Linux ou Windows com o Docker e Docker Compose instalados.
Caso você ainda não tenha instalado Docker e Docker Compose, você pode seguir as informações neste outro artigo onde tratamos da instalação em um computador Linux com Ubuntu 22.04.
3. Arquivo docker-compose.yml
Como já sabemos para trabalhar com o Docker Compose, precisamos de um arquivo yaml para configurar os nossos containers. Sendo assim vamos criar um diretório chamado kafka-cluster-with-ui e dentro dele um arquivo yaml com as configurações de nossos containers:
$ mkdir kafka-cluster-with-ui && cd kafka-cluster-with-ui
$ touch docker-compose.yml && nano docker-compose.yml
Agora vamos adicionar as configurações de nossos containers:
---
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.2.1
hostname: zookeeper
container_name: zookeeper
ports:
- '2181:2181'
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
broker:
image: confluentinc/cp-server:7.2.1
hostname: broker
container_name: broker
depends_on:
- zookeeper
ports:
- '9092:9092'
- '9101:9101'
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_METRIC_REPORTERS: io.confluent.metrics.reporter.ConfluentMetricsReporter
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_CONFLUENT_LICENSE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_CONFLUENT_BALANCER_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_JMX_PORT: 9101
KAFKA_JMX_OPTS: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka0 -Dcom.sun.management.jmxremote.rmi.port=9101
KAFKA_CONFLUENT_SCHEMA_REGISTRY_URL: http://schema-registry:8081
CONFLUENT_METRICS_REPORTER_BOOTSTRAP_SERVERS: broker:29092
CONFLUENT_METRICS_REPORTER_TOPIC_REPLICAS: 1
CONFLUENT_METRICS_ENABLE: 'true'
CONFLUENT_SUPPORT_CUSTOMER_ID: 'anonymous'
schema-registry:
image: confluentinc/cp-schema-registry:7.2.1
hostname: schema-registry
container_name: schema-registry
depends_on:
- broker
ports:
- '8081:8081'
environment:
SCHEMA_REGISTRY_HOST_NAME: schema-registry
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: 'broker:29092'
SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081
connect:
image: cnfldemos/cp-server-connect-datagen:0.5.3-7.1.0
hostname: connect
container_name: connect
depends_on:
- broker
- schema-registry
ports:
- '8083:8083'
environment:
CONNECT_BOOTSTRAP_SERVERS: 'broker:29092'
CONNECT_REST_ADVERTISED_HOST_NAME: connect
CONNECT_GROUP_ID: compose-connect-group
CONNECT_CONFIG_STORAGE_TOPIC: docker-connect-configs
CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: 1
CONNECT_OFFSET_FLUSH_INTERVAL_MS: 10000
CONNECT_OFFSET_STORAGE_TOPIC: docker-connect-offsets
CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: 1
CONNECT_STATUS_STORAGE_TOPIC: docker-connect-status
CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: 1
CONNECT_KEY_CONVERTER: org.apache.kafka.connect.storage.StringConverter
CONNECT_VALUE_CONVERTER: io.confluent.connect.avro.AvroConverter
CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: http://schema-registry:8081
# CLASSPATH required due to CC-2422
CLASSPATH: /usr/share/java/monitoring-interceptors/monitoring-interceptors-7.2.1.jar
CONNECT_PRODUCER_INTERCEPTOR_CLASSES: 'io.confluent.monitoring.clients.interceptor.MonitoringProducerInterceptor'
CONNECT_CONSUMER_INTERCEPTOR_CLASSES: 'io.confluent.monitoring.clients.interceptor.MonitoringConsumerInterceptor'
CONNECT_PLUGIN_PATH: '/usr/share/java,/usr/share/confluent-hub-components'
CONNECT_LOG4J_LOGGERS: org.apache.zookeeper=ERROR,org.I0Itec.zkclient=ERROR,org.reflections=ERROR
kafka-ui:
image: provectuslabs/kafka-ui
hostname: kafka-ui
container_name: kafka-ui
ports:
- '8080:8080'
depends_on:
- zookeeper
- broker
- schema-registry
- connect
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=local
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=broker:29092
- KAFKA_CLUSTERS_0_METRICS_PORT=9101
- KAFKA_CLUSTERS_0_SCHEMAREGISTRY=http://schema-registry:8081
- KAFKA_CLUSTERS_0_KAFKACONNECT_0_NAME=first
- KAFKA_CLUSTERS_0_KAFKACONNECT_0_ADDRESS=http://connect:8083
- DYNAMIC_CONFIG_ENABLED='true'
Estamos implantando neste arquivo uma instância do zookeeper
, um broker
do kafka, uma instância do schema-registry
, um do kafka-connect
e para gerenciar todo o cluster o kafka-ui
.
Para subir nosso cluster executamos o comando abaixo:
$ docker compose -f docker-compose.yml up -d
Podemos então executar o comando abaixo para verificar se o cluster está funcionando:
$ docker compose -f docker-compose.yml ps
Iremos obter uma saída semelhante a seguir:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
broker confluentinc/cp-server:7.2.1 "/etc/confluent/dock…" broker About a minute ago Up About a minute 0.0.0.0:9092->9092/tcp, :::9092->9092/tcp, 0.0.0.0:9101->9101/tcp, :::9101->9101/tcp
connect cnfldemos/cp-server-connect-datagen:0.5.3-7.1.0 "/etc/confluent/dock…" connect About a minute ago Up About a minute 0.0.0.0:8083->8083/tcp, :::8083->8083/tcp, 9092/tcp
kafka-ui provectuslabs/kafka-ui "/bin/sh -c 'java --…" kafka-ui About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
schema-registry confluentinc/cp-schema-registry:7.2.1 "/etc/confluent/dock…" schema-registry About a minute ago Up About a minute 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp
zookeeper confluentinc/cp-zookeeper:7.2.1 "/etc/confluent/dock…" zookeeper About a minute ago Up About a minute 2888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 3888/tcp
Podemos então agora acessar o kafka-ui em http://localhost:8080.
fig. 1 - visão geral do kafka-ui
4. Executando testes
Agora que já estamos com acesso ao cluster pela interface web, vamos criar um tópico
conforme a seguir e publicar algumas mensagens para que possamos consumir pelo console utilizando o kafka-console-consumer
.
fig. 2 - criação do tópico utilizando o kafka-ui
Neste artigo vimos como realizar o download do apache kafka e utilizar o cli para se comunicar com o broker, para mais detalhes basta consulta-lo novamente.
Agora vamos nos conectar ao nosso broker
e consumir as mensagens do tópico recém-criado.
Para isso abra o terminal e digite o comando a seguir:
$ ./bin/kafka-console-consumer.sh --topic posts-like --from-beginning --bootstrap-server localhost:9092
Voltemos então para nossa interface web para publicar algumas mensagens e acompanhar o consumo pelo nosso consumer
no console.
fig. 3 - produzindo mensagens pelo kafka-ui
No próximo teste iremos fazer o inverso, iremos publicar mensagnes pelo nosso console e acompanhar o consumo pelo kafka-ui.
Para isso inicie o nosso produtor
com o comando a seguir:
$ ./bin/kafka-console-producer.sh --topic posts-like --bootstrap-server localhost:9092
fig. 4 - consumindo mensagens pelo kafka-ui
Conclusão
Neste artigo reallizamos a instalação de um ambiente completo do Apache kafka com recursos além dos utilizados aqui, mas com os recursos mínimos para aplicações de grande escala, tudo isso utilizando apenas o Docker Compose.
Vimos também como realizar a administração do nosso cluster a partir da interface web utilizando a ferramenta Open-Source kafka-ui.
Continue nos acompanhando pois nos próximos artigos iremos criar uma aplicação completa em microserviços utilizando tudo o que vimos até aqui além do schema-registry
e kafka-connect
.
E é isso por hoje, pessoal!
Chegamos ao final de mais um artigo, espero que tenha sido útil e que você tenha aprendido algo novo.
Caso tenha alguma dúvida, comentário ou tenha encontrado algum erro, por favor, envie-me um email. Ficarei feliz em ouvir de você.
Se desejar receber novos artigos diretamente em seu e-mail, por favor, assine a nossa Newsletter. E se você já é um assinante, muito obrigado!
Aproveito e deixo um convite para nos conectarmos no Twitter e LinkedIn.
👋 Obrigado por ler até o final e até o próximo artigo !!!