premisa
Entre ellos, docker-compose no es necesario. También es posible usar docker solo. Aquí presentamos principalmente docker y docker-compose.
implementación de Docker
La implementación de Docker de Kafka es muy simple, solo se necesitan dos comandos para completar la implementación del servidor Kafka.
docker run -d --name zookeeper -p 2181:2181 wurstmeister/zookeeper
docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 --link zookeeper -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.60(机器IP):9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -t wurstmeister/kafka
Dado que kafka necesita trabajar con el guardián del zoológico, es necesario implementar un guardián del zoológico, pero con Docker es muy fácil de implementar.
Puede docker ps
verificar el estado de los dos contenedores, que no se mostrará aquí.
A continuación, puede probar los productores y consumidores.
Utilice las propias herramientas de Kafka para producir y consumir pruebas de mensajes
- Primero, ingrese al contenedor docker de kafka
docker exec -it kafka sh
-
Ejecutar consumidores y monitorear mensajes
kafka-console-consumer.sh --bootstrap-server 192.168.1.60:9092 --topic kafeidou --from-beginning
-
Abra una nueva ventana ssh, también ingrese al contenedor kafka, ejecute el siguiente comando para producir mensajes
kafka-console-producer.sh --broker-list 192.168.1.60(机器IP):9092 --topic kafeidou
Luego de ingresar este comando, ingresarás a la consola, puedes ingresar cualquier mensaje que quieras enviar, envía uno aquí
hello
>> >hello > > >
- Como puede ver, después de ingresar un mensaje en la consola del productor, la consola del consumidor vio inmediatamente el mensaje
Hasta ahora, se ha completado un completo saludo al mundo de Kafka. Implementación de Kafka más pruebas de productores y consumidores.
Prueba a través del código java
- Cree un nuevo proyecto de maven y agregue las siguientes dependencias
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.11</artifactId> <version>0.11.0.2</version> </dependency>
- Código de
productor producer.java
import org.apache.kafka.clients.producer.*;
import java.util.Date;
import java.util.Properties;
import java.util.Random;
public class HelloWorldProducer {
public static void main(String[] args) {
long events = 30;
Random rnd = new Random();
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.1.60:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("message.timeout.ms", "3000");
Producer<String, String> producer = new KafkaProducer<>(props);
String topic = "kafeidou";
for (long nEvents = 0; nEvents < events; nEvents++) {
long runtime = new Date().getTime();
String ip = "192.168.2." + rnd.nextInt(255);
String msg = runtime + ",www.example.com," + ip;
System.out.println(msg);
ProducerRecord<String, String> data = new ProducerRecord<String, String>(topic, ip, msg);
producer.send(data,
new Callback() {
public void onCompletion(RecordMetadata metadata, Exception e) {
if(e != null) {
e.printStackTrace();
} else {
System.out.println("The offset of the record we just sent is: " + metadata.offset());
}
}
});
}
System.out.println("send message done");
producer.close();
System.exit(-1);
}
}
- Código de
consumidor consumer.java
import java.util.Arrays;
import java.util.Properties;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
public class HelloWorldConsumer2 {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.1.60:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG ,"kafeidou_group") ;
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");
props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put("auto.offset.reset", "earliest");
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("kafeidou"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(1000);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
}
}
}
- Ejecute el productor y el consumidor por separado para
imprimir el mensaje.
Mensaje impreso del consumidor1581651496176,www.example.com,192.168.2.219 1581651497299,www.example.com,192.168.2.112 1581651497299,www.example.com,192.168.2.20
Sitio del código fuente: FISHStack / kafka-demooffset = 0, key = 192.168.2.202, value = 1581645295298,www.example.com,192.168.2.202 offset = 1, key = 192.168.2.102, value = 1581645295848,www.example.com,192.168.2.102 offset = 2, key = 192.168.2.63, value = 1581645295848,www.example.com,192.168.2.63
Implementar Kafka mediante docker-compose
Primero cree un archivo docker-compose.yml
version: '3.7'
services:
zookeeper:
image: wurstmeister/zookeeper
volumes:
- ./data:/data
ports:
- 2182:2181
kafka9094:
image: wurstmeister/kafka
ports:
- 9092:9092
environment:
KAFKA_BROKER_ID: 0
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.1.60:9092
KAFKA_CREATE_TOPICS: "kafeidou:2:0" #kafka启动后初始化一个有2个partition(分区)0个副本名叫kafeidou的topic
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
volumes:
- ./kafka-logs:/kafka
depends_on:
- zookeeper
La implementación es muy simple, simplemente docker-compose.yml
ejecute en el directorio de archivos docker-compose up -d
y el método de prueba es el mismo que el anterior.
Este docker-compose hace más cosas que el método de la ventana acoplable anterior.
- Persistencia de datos. Se cuelgan dos directorios en el directorio actual para almacenar los datos de zookeeper y kafka respectivamente. Por supuesto
docker run
, agregar el comando-v 选项
también puede lograr este efecto. - Kafka inicializará un tema con particiones después de que se inicie. De manera similar, también es posible
docker run
agregarlo en ese momento-e KAFKA_CREATE_TOPICS=kafeidou:2:0
.
Resumen: primero se recomienda la implementación de docker-compose
¿por qué?
Debido a la implementación simple con Docker, si hay cambios (por ejemplo: cambiar el número de puerto abierto al mundo exterior), Docker debe detener el contenedor docker stop 容器ID/容器NAME
, luego eliminar el contenedor docker rm 容器ID/容器NAME
y finalmente iniciar el nuevo contenedor.docker run ...
Y si modificas el contenido en el caso de la implementación de docker-compose, solo necesitas modificar el lugar correspondiente del archivo docker-compose.yml, por ejemplo 2181:2181改成2182:2182
, y luego ejecutarlo nuevamente en el directorio correspondiente al docker-compose. yml para docker-compose up -d
lograr el efecto actualizado.
> ¡Originado en el lanzamiento de cuatro granos de café !
> Siga la cuenta oficial -> [Four Coffee Beans] Obtenga el contenido más reciente