之前写了一篇文章,当然,来自Apache Kafka的翻译文档,让大家更能理解Kafka,地址是:
Apache Kafka® 是一个分布式流媒体平台,很适合用来处理大并发的数据,本人使用了Kafka有两年多了,非常稳定。
1.下载Kafka
我测试及开发的系统是windows,所以现在要下载一个win版本的,JDK环境就不说了,本次测试的版本号:kafka_2.12-1.0.1。
由于Kafka的运行在zookeeper环境内,所以在启动之前,我们需要安装一下zookeeper,版本号:zookeeper-3.4.11。
2.配置Kafka
如果下载下来不配置的话,会出现很多问题。
\kafka_2.12-1.0.1\config\server.properties
############################# Socket Server Settings #############################
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
# FORMAT:
# listeners = listener_name://host_name:port
# EXAMPLE:
# listeners = PLAINTEXT://your.host.name:9092
#listeners=PLAINTEXT://:9092
port=9092
host.name=127.0.0.1
…
############################# Log Basics #############################
# A comma seperated list of directories under which to store log files
#log.dirs=/tmp/kafka-logs
log.dirs=D:\\kafka\\logs
示例的配置有删减,因为事实上我只配置了这几点而已:
port=9092
host.name=127.0.0.1
log.dirs=D:\\kafka\\logs
\zookeeper-3.4.11\conf\zoo.cfg
dataDir=D:\\kafka\\logs
\kafka_2.12-1.0.1\config\zookeeper.properties
dataDir=D:\\kafka\\logs
到这里,基本上就可以运行了,现在首先启动zookeeper服务器:
zkServer //简单直接
./zookeeper-3.4.11/bin/zkServer.cmd //或许可以这样子
./zkServer.sh start //linux 可能是这样子
然后启动kafka服务器:
.\kafka_2.12-1.0.1\bin\windows\kafka-server-start.bat .\kafka_2.12-1.0.1\config\server.properties
./kafka-server-start.sh ../config/server.properties //linux 启动
./kafka-server-start.sh ../config/server.properties 1>/dev/null 2>&1 & //linux 后台启动
nohup ./kafka-server-start.sh ../config/server.properties & //linux 后台启动
服务器启动完了,现在来写代码,配置kafka
3.集成Kafka
maven
org.springframework.kafka
spring-kafka
1.3.0.RELEASE
配置生产者
private final Map producerArg = new HashMap<>();
private DefaultKafkaProducerFactory kafkaProducerFactory;
private KafkaTemplate kafkaTemplate;
private void initArg() {
producerArg.put("bootstrap.servers", "127.0.0.1:9092");
producerArg.put("group.id", "100");
producerArg.put("compression.type", "gzip");
producerArg.put("reconnect.backoff.ms ", 20000);
producerArg.put("retry.backoff.ms", 20000);
producerArg.put("retries", 30);
producerArg.put("batch.size", "16384");
producerArg.put("linger.ms", "50");
producerArg.put("acks", "all");
producerArg.put("buffer.memory", "33554432");
producerArg.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
producerArg.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
}
/**
* 创建一个生产者工厂类
* @return
*/
public DefaultKafkaProducerFactory getKafkaProducerFactory() {
if (kafkaProducerFactory == null) {
kafkaProducerFactory = new DefaultKafkaProducerFactory(producerArg);
}
return kafkaProducerFactory;
}
/**
* 创建一个消息模板
* @param topic 默认的TOPIC
* @param listener 生产者监听,如不需要则传入null
* @return KafkaTemplate
*/
@Override
public KafkaTemplate createKafkaTemplate(String topic, ProducerListener listener) {
if (kafkaTemplate == null) {
kafkaTemplate = new KafkaTemplate(this.getKafkaProducerFactory());
kafkaTemplate.setDefaultTopic(TOPIC_DEFAULT);
kafkaTemplate.setProducerListener(listener);
}
return kafkaTemplate;
}
/**
* 发布消息
* @param topic TopicName
* @param message 消息字符串,通常为JSON string
* @param isUsePartition 是否使用分区
* @param partitionNum 分区的数量
* @param role 用来区分消息key值
* @return
*/
@Override
public boolean send(String topic, String message, boolean isUsePartition, Integer partitionNum, String role) {
if (role == null) {
role = ROLE_DEFAULT;
}
String key = role + "_" + message.hashCode();
ListenableFuture> result;
if (isUsePartition) {
int index = getPartitionIndex(key, partitionNum);
result = kafkaTemplate.send(topic, index, key, message);
} else {
result = kafkaTemplate.send(topic, key, message);
}
return checkResult(result);
}
配置消费者
private f