文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、简介
Kafka is a distributed,partitioned,replicated commit logservice。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
二、安装步骤
博主最近在学习有关kafka的配置安装以及在spring的集成使用。但网上关于kafka的配置参考资料基本都是于linux下的配置,于是博主在整理了相关windows下kafka的配置记录在博客里。由于是简单配置所以在这里只建了一个topic以及一个producer和两个consumer。
关于kafka具体是什么以及他的设计原理使用场景等等请看上篇博客,转自大佬。传送门:http://www.cnblogs.com/wdfordream/p/7324975.html。
在官网上下载 zookeeper和kafka(我下的版本kafka_2.11-0.11.0.0,这个版本中bin目录下有windows目录),注意不要下载源码包(名字中带有src),否则启动的时候会报错。
1、配置好jdk环境
2、zookeeper配置
解压zookeeper到指定目录,找到解压后目录中conf文件夹中zoo_sample - 副本.cfg文件,复制在conf中改名为zoo.cfg。在bin文件夹中打开zkServer.bat启动zookeeper。
至此,zookeeper启动完成。
3、kafka配置
解压kafka到指定目录。查看kafka根目录中config文件夹下server.properties,确认其中关于zookeeper的连接端口和zookeep中zoo.cfg的端口一致。
3.1、启动kafka
在cmd中进入kafka根目录。输入以下命令:
.\bin\windows\kafka-server-start.bat .\config\server.properties
kafka启动成功
3.2、创建topic
在cmd中进入kafka\bin\windows目录,输入以下命令:
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
创建成功
3.3、创建kafka producer
在cmd中进入kafka\bin\windows目录,输入以下命令:
kafka-console-producer.bat --broker-list localhost:9092 --topic test
注意这里的端口和server.properties的端口号一致。
3.4创建consumer
在cmd中进入kafka\bin\windows目录,输入以下命令:
kafka-console-consumer.bat --zookeeper localhost:2181 --topic test (旧版本)
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning(新版本)
以同样的方式创建另一个consumer。
4、环境测试
在producer中输入一句话并回车,可以在两个consumer中得到相关信息。
5、Kafka查看topic、consumer group状态命令
原文链接:https://www.cnblogs.com/AcAc-t/p/kafka_topic_consumer_group_command.html
最近工作中遇到需要使用kafka的场景,测试消费程序启动后,要莫名的过几十秒乃至几分钟才能成功获取到到topic的partition和offset,而后开始消费数据,于是学习了一下查看kafka broker里topic和consumer group状态的相关命令,这里记录一下。
命令参考自《Kafka: The Definitive Guide》 Chapter 9 Administrating Kafka
以下命令中使用的zookeeper配置地址为127.0.0.1:2181,bootstrap–server(即broker)地址为: 127.0.0.1:9292
1,查看kafka topic列表,使用–list参数
bin/kafka-topics.sh --zookeeper 127.0.0.1:2181 --list
__consumer_offsets
lx_test_topic
test
2,查看kafka特定topic的详情,使用–topic与–describe参数
bin/kafka-topics.sh --zookeeper 127.0.0.1:2181 --topic lx_test_topic --describe
Topic:lx_test_topic PartitionCount:1 ReplicationFactor:1 Configs:
Topic: lx_test_topic Partition: 0 Leader: 0 Replicas: 0 Isr: 0
列出了lx_test_topic的parition数量、replica因子以及每个partition的leader、replica信息
3,查看consumer group列表,使用–list参数
查看consumer group列表有新、旧两种命令,分别查看新版(信息保存在broker中)consumer列表和老版(信息保存在zookeeper中)consumer列表,因而需要区分指定bootstrap–server和zookeeper参数:
bin/kafka-consumer-groups.sh --new-consumer --bootstrap-server 127.0.0.1:9292 --list
lx_test
bin/kafka-consumer-groups.sh --zookeeper 127.0.0.1:2181 --list
console-consumer-86845
console-consumer-11967
4,查看特定consumer group 详情,使用–group与–describe参数
同样根据新/旧版本的consumer,分别指定bootstrap-server与zookeeper参数:
bin/kafka-consumer-groups.sh --new-consumer --bootstrap-server 127.0.0.1:9292 --group lx_test --describe
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG OWNER
lx_test lx_test_topic 0 465 465 0 kafka-python-1.3.1_/127.0.0.1
bin/kafka-consumer-groups.sh --zookeeper 127.0.0.1:2181 --group console-consumer-11967 --describe
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG OWNER
Could not fetch offset from zookeeper for group console-consumer-11967 partition [lx_test_topic,0] due to missing offset data in zookeeper.
console-consumer-11967 lx_test_topic 0 unknown 465 unknown console-consumer-11967_aws-lx-1513787888172-d3a91f05-0
其中依次展示group名称、消费的topic名称、partition id、consumer group最后一次提交的offset、最后提交的生产消息offset、消费offset与生产offset之间的差值、当前消费topic-partition的group成员id(不一定包含hostname)
上面示例中console-consumer-11967是为了测试临时起的一个console consumer,缺少在zookeeper中保存的current_offset信息。
5.创建topic命令
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
6.启动生产者控制台命令
kafka-console-producer.bat --broker-list localhost:9092 --topic test
7.启动消费者监听控制点命令
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test
6、其他相关命令
查看已建立的topics:kafka-topics.bat --list --zookeeper localhost:2181
查看每个节点信息 :kafka-topics.bat --describe --zookeeper localhost:2181 --topic my-replicated-topic
7、问题整理
6.1、kafka启动时报异常Caused by:java.lang.OutOfMemoryError:Map failed
在这里博主的办法是将kafka-server-run.bat里的参数set KAFKA_HEAP_OPTS=-Xmx512M -Xms512M改为256M,如果有更好的解决办法谢谢大家能告诉我。
6.2、kafka启动时报异常Caused by: java.nio.file.FileSystemException: \tmp\kafka-logs\topic.alarmMatchFace-0\00000000000000009163.log -> \tmp\kafka-logs\topic.alarmMatchFace-0\00000000000000009163.log.deleted: 另一个程序正在使用此文件,进程无法访问。
主要是因为tmp/kafka-logs文件的日志达到了1G且未被清理。由于这样的错误是在kafka服务关闭后重启kafka服务引起的,博主暂无什么好的解决方法,每次把tmp下的kafka-logs文件夹删除,再启动kafka服务就不会报错了,希望各位大大如果有好的方法能告知我一下,谢谢啦。
6.3、kafka 创建消费者报错 consumer zookeeper is not a recognized option
在做kafka测试的时候,使用命令bin/kafka-console-consumer.sh --zookeeper 192.168.0.140:2181,192.168.0.141:2181 --topic test --from-beginning启动消费者,发现一只报错consumer zookeeper is not a recognized option,搜索了半天,一只没有解决,最后,换了一个低版本的kakfa,发现在启动的时候说使用 --zookeeper是一个过时的方法,此时,才知道原来在最新的版本中,这种启动方式已经被删除了,
最后附上0.90版本之后启动消费者的方法: bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
8、springboot集成kafka
1.kafka配置类KafkaConfig
package com.xxx;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.listener.AbstractMessageListenerContainer;
import org.springframework.kafka.listener.config.ContainerProperties;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableKafka
public class KafkaConfig {
@Value("${spring.kafka.bootstrap-servers}")
private String kafkaServers;
@Value("${spring.kafka.listener.concurrency}")
private Integer listenerConcurrency;
@Value("${spring.kafka.consumer.enable-auto-commit}")
private Boolean consumerEnableAutoCommit;
@Bean
public KafkaTemplate<String, Object> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@Bean
public ProducerFactory<String, Object> producerFactory() {
return new DefaultKafkaProducerFactory<>(producerConfigs());
}
@Bean
public Map<String, Object> producerConfigs() {
Map<String, Object> props = new HashMap<>(16);
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServers);
props.put(ProducerConfig.RETRIES_CONFIG, "3");
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "gzip");
props.put(ProducerConfig.BATCH_SIZE_CONFIG, 200);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer");
return props;
}
@Bean("myKafkaContainerFactory")
ConcurrentKafkaListenerContainerFactory<Object, Object> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setConcurrency(listenerConcurrency);
//factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL_IMMEDIATE);
return factory;
}
@Bean
public ConsumerFactory< Object,Object> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>(16);
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServers);
props.put(ConsumerConfig.GROUP_ID_CONFIG, KafkaConstant.FRONT_TOPIC_GROUP);
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, consumerEnableAutoCommit);
props.put(ConsumerConfig.CLIENT_ID_CONFIG, "localhost" + "-h5-consumer");
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
return props;
}
}
2.生产者类KafkaProducer
package com.xxx;
import com.alibaba.fastjson.JSONObject;
import com.xxx.KafkaConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
/**
* Kafka生产者
* @version 1.0 since 2021-01-15
*/
@Component
@Slf4j
public class KafkaProducer {
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
@Value("${topic.name}")
private String topicName;
public void send(Object obj) {
String obj2String = JSONObject.toJSONString(obj);
log.info("准备发送消息为:{}", obj2String);
//发送消息
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topicName, obj);
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onFailure(Throwable throwable) {
//发送失败的处理
log.info(KafkaConstant.FRONT_TOPIC_GROUP + " - 生产者 发送消息失败:" + throwable.getMessage());
}
@Override
public void onSuccess(SendResult<String, Object> stringObjectSendResult) {
//成功的处理
log.info(KafkaConstant.FRONT_TOPIC_GROUP + " - 生产者 发送消息成功:" + stringObjectSendResult.toString());
}
});
}
}
2.消费者类KafkaConsumer
package com.xxx.consumer;
import com.xxx.KafkaConstant;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* Kafka消费者
*
* @author v_honwang
* @version 1.0 since 2021-01-15
*/
@Component
@Log4j2
public class KafkaConsumer {
@KafkaListener(topics = {"#{'${topic.name}'.split(',')}"},containerFactory="myKafkaContainerFactory")
public void topicTest(String record, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional message = Optional.ofNullable(record);
if (message.isPresent()) {
Object msg = message.get();
log.info("topic_test 消费了: Topic:" + topic + ",Message:" + msg);
}
}
}
application.properties注入的配置
#==============kafka相关配置
spring.kafka.bootstrap-servers=localhost:9092
topic.name=test
#spring.kafka.bootstrap-servers=10.241.131.98:8080
spring.kafka.producer.buffer-memory=33554432
spring.kafka.listener.concurrency=3
spring.kafka.consumer.enable-auto-commit=true
#spring.kafka.producer.retries=0
#spring.kafka.producer.batch-size=16384
#spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
#spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
#spring.kafka.producer.acks=1
#spring.kafka.consumer.auto-commit-interval=1S
#spring.kafka.consumer.auto-offset-reset=earliest
#spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
#spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
#spring.kafka.listener.ack-mode=manual_immediate
#spring.kafka.listener.missing-topics-fatal=false
问题总结:
springboot 多topic 动态配置
项目中需要能够动态配置topic进行消费。
1.application.properties中配置topicName=topic1,topic2
2.@KafkaListener(topics = {"#{’${topicName}’.split(’,’)}"})
3.pom文件引入springkafka-1.2.2,不能引入springkafka-1.1.0。