Producer部分

Producer在实例化后, 对外提供send方法, 用于将数据送到指定的topic和partition; 以及在退出时需要的destroy方法.

接口 KafkaProducer.java

import java.util.List;
import java.util.Properties; public interface KafkaProducer<D> { default void init() {
}
default void destroy() {
}
boolean send(String topic, D data);
boolean send(String topic, Integer partition, D data);
boolean send(String topic, List<D> dataList);
boolean send(String topic, Integer partition, List<D> dataList); /**
* 默认配置
*/
default Properties getDefaultProps() {
Properties props = new Properties();
props.put("acks", "1");
props.put("retries", 1);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 32 * 1024 * 1024L);
return props;
}
}

参数说明

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
// The acks config controls the criteria under which requests are considered complete. The "all" setting we have specified will result in blocking on the full commit of the record, the slowest but most durable setting.
props.put("acks", "all");
// If the request fails, the producer can automatically retry, though since we have specified retries as 0 it won't. Enabling retries also opens up the possibility of duplicates (see the documentation on message delivery semantics for details).
props.put("retries", 0);
// The producer maintains buffers of unsent records for each partition. These buffers are of a size specified by the batch.size config. Making this larger can result in more batching, but requires more memory (since we will generally have one of these buffers for each active partition).
props.put("batch.size", 16384);
// By default a buffer is available to send immediately even if there is additional unused space in the buffer. However if you want to reduce the number of requests you can set linger.ms to something greater than 0. This will instruct the producer to wait up to that number of milliseconds before sending a request in hope that more records will arrive to fill up the same batch.
props.put("linger.ms", 1);
// 生产者缓冲大小,当缓冲区耗尽后,额外的发送调用将被阻塞。时间超过max.block.ms将抛出TimeoutException
props.put("buffer.memory", 33554432);
// The key.serializer and value.serializer instruct how to turn the key and value objects the user provides with their ProducerRecord into bytes. You can use the included ByteArraySerializer or StringSerializer for simple string or byte types.
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

实现 KafkaProducerImpl.java

import com.google.common.base.Strings;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.util.List;
import java.util.Map;
import java.util.Properties; public class KafkaProducerImpl<D> implements KafkaProducer<D> {
private static final Logger logger = LoggerFactory.getLogger(KafkaProducerImpl.class);
private final Producer<D, D> producer; public KafkaProducerImpl() {
Properties props = this.getDefaultProps();
props.put("bootstrap.servers", servers);
props.put("key.serializer", serializer);
props.put("value.serializer", serializer);
producer = new org.apache.kafka.clients.producer.KafkaProducer<>(props);
} @Override
public void destroy() {
if (producer != null) {
producer.close();
}
} @Override
public boolean send(String topic, D data) {
boolean isSuc = true;
try {
producer.send(new ProducerRecord<>(topic, data));
} catch (Exception e) {
isSuc = false;
logger.error(String.format("KafkaStringProducer send error.topic:[%s],data:[%s]", topic, data), e);
}
return isSuc;
} @Override
public boolean send(String topic, Integer partition, D data) {
boolean isSuc = true;
try {
producer.send(new ProducerRecord<>(topic, partition, null, data));
} catch (Exception e) {
isSuc = false;
logger.error(String.format("KafkaStringProducer send error.topic:[%s],data:[%s]", topic, data), e);
}
return isSuc;
} @Override
public boolean send(String topic, List<D> dataList) {
boolean isSuc = true;
try {
if (dataList != null) {
dataList.forEach(item -> producer.send(new ProducerRecord<>(topic, item)));
}
} catch (Exception e) {
isSuc = false;
logger.error(String.format("KafkaStringProducer send error.topic:[%s],dataList:[%s]", topic, dataList), e);
}
return isSuc;
} @Override
public boolean send(String topic, Integer partition, List<D> dataList) {
boolean isSuc = true;
try {
if (dataList != null) {
dataList.forEach(item -> producer.send(new ProducerRecord<>(topic, partition, null, item)));
}
} catch (Exception e) {
isSuc = false;
logger.error(String.format("KafkaStringProducer send error.topic:[%s],partition[%s],dataList:[%s]", topic, partition, dataList), e);
}
return isSuc;
}
}

Consumer 部分

Consumer 在实例化后, 负责将ConsumerListener添加到列表, 并订阅指定的topic, 启动一个阻塞的循环, 在收到消息后依次调用ConsumerListener进行处理

接口 KafkaConsumer.java

import java.util.Properties;

public interface KafkaConsumer {

    default void init() {
} default void destroy() {
} void start(); /**
* 默认配置
*/
default Properties getDefaultProps() {
Properties props = new Properties();
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("session.timeout.ms", "30000");
return props;
}
}  

参数说明

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
// Setting enable.auto.commit means that offsets are committed automatically with a frequency controlled by the config auto.commit.interval.ms.
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
// The deserializer settings specify how to turn bytes into objects. For example, by specifying string deserializers, we are saying that our record's key and value will just be simple strings.
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
// This consumer is subscribing to the topics foo and bar as part of a group of consumers called test as configured with group.id.
consumer.subscribe(Arrays.asList("foo", "bar"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records)
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}

实现 KafkaConsumerImpl.java

import com.google.common.base.Strings;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.util.*; public class KafkaConsumerImpl<K, V> implements KafkaConsumer {
private static final Logger logger = LoggerFactory.getLogger(KafkaConsumerImpl.class);
private final List<KafkaConsumerListener<K, V>> consumerListeners = new ArrayList<>();
private Consumer<K, V> consumer;
private boolean running = true; private final int waitingTimeout = 100; public KafkaConsumerImpl(String topic, String groupId, String deserializer) {
Properties props = this.getDefaultProps();
props.put("group.id", groupId);
props.put("bootstrap.servers", servers);
props.put("key.deserializer", deserializer);
props.put("value.deserializer", deserializer);
consumer = new org.apache.kafka.clients.consumer.KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList(topic));
} public void setConsumerListeners(List<KafkaConsumerListener<K, V>> consumerListeners) {
synchronized (this) {
this.consumerListeners.clear();
if (null != consumerListeners && 0 != consumerListeners.size()) {
consumerListeners.forEach(this.consumerListeners::add);
}
}
} public void addConsumerListener(KafkaConsumerListener<K, V> consumerListener) {
synchronized (this) {
if (null != consumerListener && !this.consumerListeners.contains(consumerListener)) {
this.consumerListeners.add(consumerListener);
}
}
} public void removeConsumerListener(KafkaConsumerListener<K, V> consumerListener) {
synchronized (this) {
if (null != consumerListener && this.consumerListeners.contains(consumerListener)) {
this.consumerListeners.remove(consumerListener);
}
}
} @Override
public void init() {
this.start();
} @Override
public void destroy() {
running = false;
} @Override
public void start() {
new Thread(() -> {
while (running) {
ConsumerRecords<K, V> records = consumer.poll(waitingTimeout);
for (ConsumerRecord<K, V> record : records) {
if (consumerListeners != null) {
K key = record.key();
if (key == null)
consumerListeners.forEach(consumer -> consumer.consume(record.value()));
else
consumerListeners.forEach(consumer -> consumer.consume(record.key(), record.value()));
}
}
}
//should use consumer in different thread, or it will throw ConcurrentModificationException
if (consumer != null) {
try {
logger.info("start to close consumer.");
consumer.close();
} catch (Exception e) {
logger.error("close kafka consumer error.", e);
}
consumer = null;
}
}).start();
}
}

接口 KafkaConsumerListener.java

public interface KafkaConsumerListener<K, V> {
void consume(V value); default void consume(K key, V value) {
consume(value);
}
}

.

在Java中使用Kafka的更多相关文章

  1. 精选干货 在java中创建kafka

    这个详细的教程将帮助你创建一个简单的Kafka生产者,该生产者可将记录发布到Kafka集群. 通过优锐课的java学习架构分享中,在本教程中,我们将创建一个简单的Java示例,该示例创建一个Kafka ...

  2. Java中的Unsafe类111

    1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoo ...

  3. Java 中的纤程库 – Quasar

    来源:鸟窝, colobu.com/2016/07/14/Java-Fiber-Quasar/ 如有好文章投稿,请点击 → 这里了解详情 最近遇到的一个问题大概是微服务架构中经常会遇到的一个问题: 服 ...

  4. spark streaming中维护kafka偏移量到外部介质

    spark streaming中维护kafka偏移量到外部介质 以kafka偏移量维护到redis为例. redis存储格式 使用的数据结构为string,其中key为topic:partition, ...

  5. CentOS中配置Kafka集群

    环境:三台虚拟机Host0,Host1,Host2 Host0:192.168.10.2 Host1:  192.168.10.3 Host2:  192.168.10.4 在三台虚拟机上配置zook ...

  6. 1.1 Introduction中 Apache Kafka™ is a distributed streaming platform. What exactly does that mean?(官网剖析)(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Apache Kafka™ is a distributed streaming p ...

  7. CentOS7安装CDH 第九章:CDH中安装Kafka

    相关文章链接 CentOS7安装CDH 第一章:CentOS7系统安装 CentOS7安装CDH 第二章:CentOS7各个软件安装和启动 CentOS7安装CDH 第三章:CDH中的问题和解决方法 ...

  8. SUSE中搭建kafka

     搭建环境: JDK: java version 1.8.0_221 zookeeper:zookeeper-3.5.2 kafka: kafka-2.11-1.1.0 一.安装JDK 由于需要jav ...

  9. Springboot中使用kafka

    注:kafka消息队列默认采用配置消息主题进行消费,一个topic中的消息只能被同一个组(groupId)的消费者中的一个消费者消费. 1.在pom.xml依赖下新添加一下kafka依赖ar包 < ...

随机推荐

  1. httpModules 不起作用 modules 不起作用 血泪经验

    本人也搜索了哏多解决方案.最后都没有解决... 劝您还会放弃把.. 如果非要用,劝您吧代码写到  Global.asax   里...(血泪经验)

  2. (使用STL中的数据结构进行编程7.3.15)UVA 630 Anagrams (II)(求一个单词在字典中出现的次数)

    /* * UVA_630.cpp * * Created on: 2013年11月4日 * Author: Administrator */ #include <iostream> #in ...

  3. 第三章 Typescript 基本数据类型

    Typescript 基本数据类型 一.基本数据类型 Boolean Number String Array Tuple Enum Any Void Null 和 Undefined Never 二. ...

  4. ie7 z-index 失效问题

    解决办法: 父级元素加上position:relative;并设置z-index. 父级元素的z-index优先,其中包含的元素的z-index是相对于父级元素的index. <div styl ...

  5. Nginx限制某个IP同一时间段的访问次数和请求数示例代码

    nginx可以通过ngx_http_limit_conn_module和ngx_http_limit_req_module配置来限制ip在同一时间段的访问次数. ngx_http_limit_conn ...

  6. bash: php: command not found

    bash: php: command not found 解决:export PATH=$PATH:/usr/local/php/bin

  7. MonoDB的数据准备

      首先是数据的录入,为了分析我们服务器集群的性能,需要准备大量的用户数据,幸运的是mtools提供了mgenerate方法供我们使用.他可以根据一个数据模版向 MongoDB 中插入任意条 json ...

  8. Install Hyper-V on Windows 10

      Enable Hyper-V to create virtual machines on Windows 10.Hyper-V can be enabled in many ways includ ...

  9. OpenGL ES 3.0之Fragment buffer objects(FBO)详解(二)

    我们可以使用帧缓冲对象来实现离屏渲染.帧缓冲对象支持下列操作 1.只使用OpenGL ES 函数创建帧缓冲区对象. 2.使用EGL context创建多个FBO. 3.创建离屏颜色.深度.模板渲染缓冲 ...

  10. 分享几套生成iMac相关高逼格免费mockup的素材和在线工具

    好久没有过来转, 今天姐姐我分享几套高逼格的iMac相关设计资源, 希望各位靓妹帅哥会喜欢, 最重要滴是,都是FREE,此处应有掌声~~~ , yeah!! iMac桌面效果Mockup 只需要下载后 ...