Kafka这个服务在启动时会依赖于Zookeeper,Kafka相关的部分数据也会存储在Zookeeper中。如果kafka或者Zookeeper中存在脏数据的话(即错误数据),这个时候虽然生产者可以正常生产消息,但是消费者会出现无法正常消费消息的情况。
所以在进行下述这个案例进行测试时,为了避免一些错误,可以将两个镜像服务全部进行重装,重装的镜像服务由于未设定数据存储方式(即采用非持久化的匿名数据卷),所以在重装以后会采用新的匿名数据卷,是一个全新的配置信息。
PS:同样是MQ,相比较而言,RabbitMQ针对异常情况的兼容处理比Kafka要好很多,使用Kafka需要有很丰富的经验,生产环境非必要不建议使用这个。
1、earliest
Windosw环境下面使用下述两个命令重装Zookeeper和Kafka:
docker run -d --name zookeeper -p 2181:2181 -t zookeeper:latest
docker run -d --name kafka -p 9092:9092 -e KAFKA_ZOOKEEPER_CONNECT=192.168.1.15:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.15:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -e TZ="Asia/Shanghai" wurstmeister/kafka:latest
假设前面的环境准备我已经完成了,现在正式进入案例测试流程。当前kafka的版本为2.8.11,Spring Boot的版本为2.7.6,在pom.xml中引入下述依赖:
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.8.11</version>
</dependency>
然后在yml配置文件进行如下配置:
spring:
kafka:
bootstrap-servers: 127.0.0.1:9092
consumer:
group-id: 0
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
auto-offset-reset: earliest
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
在项目中创建一个生产者用于往主题topic0中投递消息,如下所示:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/kafka")
public class KafkaProducer {
// 自定义的主题名称
public static final String TOPIC_NAME="topic0";
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@RequestMapping("/send")
public String send(@RequestParam("msg")String msg) {
log.info("准备发送消息为:{}",msg);
// 1.发送消息
ListenableFuture<SendResult<String,String>> future=kafkaTemplate.send(TOPIC_NAME,msg);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onFailure(Throwable throwable) {
// 2.发送失败的处理
log.error("生产者 发送消息失败:"+throwable.getMessage());
}
@Override
public void onSuccess(SendResult<String, String> stringObjectSendResult) {
// 3.发送成功的处理
log.info("生产者 发送消息成功:"+stringObjectSendResult.toString());
}
});
return "接口调用成功";
}
}
项目启动以后,如果Kafka中没有topic0这个主题,那么在利用上述接口首次往Kafka中投递消息时会创建这个主题。此处利用 /kafka/send?msg=xxx 接口往主题topic0中生产10条消息,接着再在项目中创建一个消费者用于消息主题topic0中的消息,如下所示:
import java.util.Optional;
import lombok.extern.slf4j.

本文围绕Kafka消费者的auto - offset - reset配置展开测试。介绍了Kafka依赖Zookeeper,脏数据会影响消费。通过多个案例测试了earliest、latest、none配置及默认配置下消费者的消费情况,还测试了多消费者组消费同一主题的不同场景,总结了不同配置的作用。
最低0.47元/天 解锁文章
1879

被折叠的 条评论
为什么被折叠?



