Kafka--JAVA API(Producer和Consumer)

Kafka 版本2.11-0.9.0.0

producer

package com.yzy.spark.kafka;

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage; import kafka.producer.ProducerConfig; import java.util.Properties; /**
* Producer
*/
public class KafkaProducer extends Thread{
private String topic;
//--1
private Producer<String, String> producer;
public KafkaProducer(String topic){
this.topic=topic; Properties properties = new Properties(); //--2
properties.put("metadata.broker.list",KafkaProperties.BROKER_LIST);
properties.put("serializer.class","kafka.serializer.StringEncoder");
properties.put("request.require.acks","1");
// properties.put("partitioner.class","com.yzy.spark.kafka.MyPartition");
ProducerConfig config=new ProducerConfig(properties);
producer=new Producer<>(config);
} @Override
public void run() {
int messageNo=1;
while (true){
String message="message"+ messageNo;
producer.send(new KeyedMessage<String,String>("test2",String.valueOf(messageNo),message)); //--4
System.out.println("Sent:"+message);
messageNo++;
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

1.定义Producer<K,V>对象,这里要注意泛型类型,之后的KeyedMessage<K,V>的泛型类型和Producer<K,V>相同。

2.创建Producer<K,V>对象需要传入一个ProducerConfig对象,而ProducerConfig对象需要由Properties对象构造,properties的属性设置可以查看ProducerConfig源码,注释很详细(个别属性在ProducerConfig父类AsyncProducerConfig 和 SyncProducerConfigShared中)。

3.该属性可以指定partitioner,如果不设置默认会设为kafka.producer.DefaultPartitioner。

4.看看KeyedMessage的源码:

case class KeyedMessage[K, V](topic: String, key: K, partKey: Any, message: V) {
if(topic == null)
throw new IllegalArgumentException("Topic cannot be null.") def this(topic: String, message: V) = this(topic, null.asInstanceOf[K], null, message) def this(topic: String, key: K, message: V) = this(topic, key, key, message) def partitionKey = {
if(partKey != null)
partKey
else if(hasKey)
key
else
null
} def hasKey = key != null
}

参数有4个,topic必填,message是消息,通常只填这两个参数即可发送消息。key和partKey是用于partition的参数,partKey的优先级高于key,但是partKey只对当前消息起作用,key和partKey只能是String类型。下面来看看partition策略和key。

partition

先在服务器端将topic test2的partitions设定为3

kafka-topics.sh --alter --zookeeper localhost:2181 --partitions 3 --topic test2

然后回到客户端看看kafka.producer.DefaultPartitioner源码


package kafka.producer import kafka.utils._
import org.apache.kafka.common.utils.Utils class DefaultPartitioner(props: VerifiableProperties = null) extends Partitioner {
private val random = new java.util.Random def partition(key: Any, numPartitions: Int): Int = {
Utils.abs(key.hashCode) % numPartitions
}
}

该类有一个方法 def partition(key: Any, numPartitions: Int),第一个参数为上文所说的key或partKey,第二个为partitions的数量,传入的值就是在服务器设置的值(3),将key的hashCode对numPartitions取余得到结果(选择对应编号的partition)

我们可以自己定义一个partition.class并配置到properties属性中,这里给一个简单的例子:

package com.yzy.spark.kafka;

import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties; public class MyPartition implements Partitioner {
public MyPartition(VerifiableProperties properties){ }
@Override
public int partition(Object key, int numPartitions) {
System.out.println("numPartitions:"+numPartitions);
return key.hashCode()%numPartitions; }
}

Consumer

package com.yzy.spark.kafka;

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties; public class KafkaConsumer extends Thread{
private String topic;
private String groupId; public KafkaConsumer(String topic,String groupId){
this.topic=topic;
this.groupId=groupId; } private ConsumerConnector createConnector(){
Properties properties=new Properties();//--1
properties.put("zookeeper.connect",KafkaProperties.ZK);
properties.put("group.id",groupId);
properties.put("auto.offset.reset", "largest");//--2
ConsumerConfig consumerConfig = new ConsumerConfig(properties);
return Consumer.createJavaConsumerConnector(consumerConfig);
} @Override
public void run() {
ConsumerConnector consumerConnector=this.createConnector();
Map<String,Integer> topicCountMap=new HashMap<>();
topicCountMap.put(topic,1);
Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = consumerConnector.createMessageStreams(topicCountMap);
KafkaStream<byte[], byte[]> stream = messageStreams.get(topic).get(0);
ConsumerIterator<byte[], byte[]> iterator = stream.iterator(); while(iterator.hasNext()){
String message=new String(iterator.next().message());
}
}
}

Consumer相关的东西比较多,涉及到group和partition机制,以官方文档为准。

1.properties和producer一样看源码配置。

2.这个属性和shell命令中的--from-beginning对应。可以填smallest(从头读取)和largest(默认值,读取最新的元素,严格来说是最新的offset位置开始读取)。注意:每一次一个新的consumer试图去消费一个topic时,都是从所在group的largest offset位置读取,即也可通过设置group.id来实现from-beginning,只要将每个consumer的group.id都设置为一个新值即可,例如properties.put("group.id", UUID.randomUUID().toString());

Kafka-JavaAPI(Producer And Consumer)的更多相关文章

  1. Kafka客户端Producer与Consumer

    Kafka客户端Producer与Consumer 一.pom.xml 二.相关配置文件 producer.properties log4j.properties base.properties 三. ...

  2. Kafka的Producer和Consumer源码学习

    先解释下两个概念: high watermark (HW) 它表示已经被commited的最后一个message offset(所谓commited, 应该是ISR中所有replica都已写入),HW ...

  3. Kafka的Producer以及Consumer远程调用问题

    公司需要分布式的JMS,所以研究了Kafka,之前在本地都没有出现问题,但是在服务器上布Kafka的时候发现了消费者无法消费的问题. kafka布到一台服务器上面,由于业务原因,producer和ka ...

  4. SpringBoot整合kafka(实现producer和consumer)

    本文代码使用的是Spring Boot 2.1.8.RELEASE 版本 <parent> <groupId>org.springframework.boot</grou ...

  5. Apache Kafka - KIP-42: Add Producer and Consumer Interceptors

    kafka 0.10.0.0 released   Interceptors的概念应该来自flume 参考,http://blog.csdn.net/xiao_jun_0820/article/det ...

  6. [Kafka] - Kafka Java Producer代码实现

    根据业务需要可以使用Kafka提供的Java Producer API进行产生数据,并将产生的数据发送到Kafka对应Topic的对应分区中,入口类为:Producer Kafka的Producer ...

  7. 057 Java中kafka的Producer程序实现

    1.需要启动的服务 这里启动的端口是9092. bin/kafka-console-consumer.sh --topic beifeng --zookeeper linux-hadoop01.ibe ...

  8. springboot kafka集成(实现producer和consumer)

    本文介绍如何在springboot项目中集成kafka收发message. 1.先解决依赖 springboot相关的依赖我们就不提了,和kafka相关的只依赖一个spring-kafka集成包 &l ...

  9. 如何创建Kafka客户端:Avro Producer和Consumer Client

    1.目标 - Kafka客户端 在本文的Kafka客户端中,我们将学习如何使用Kafka API 创建Apache Kafka客户端.有几种方法可以创建Kafka客户端,例如最多一次,至少一次,以及一 ...

随机推荐

  1. Understanding Java Memory Model-理解java内存模型(JVM)

    from https://medium.com/platform-engineer/understanding-java-memory-model-1d0863f6d973 Understanding ...

  2. ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭。

    ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭. 问题描述 今天,在做Element+Vue项目时发现:Di ...

  3. P &R 12

    Floorplan包含: IO floorplan: 涉及板级设计.封装设计的交互,接口协议(timing相关),对一些高速接口需要做特殊考虑(如信号完整性等). Power plan:芯片的电源和低 ...

  4. 【网搜】禁止 number 输入非数字(Android仍有问题)

    目的:使用 number 表单,让其只可输入数字. 问题:ios 可正常限制,Android 仍可输入  [ e | . |  - |  + ]   这4个字符.猜测这4个字符在数值中为科学记数.小数 ...

  5. selenium 使用close和quit关闭driver的不同点

    Driver.Quit()与Driver.Close()的不同:Driver.Quit(): Quit this dirver, closing every associated windows;Dr ...

  6. 压缩和解压工具bandizip

    同质化的压缩软件 提及 Windows 平台的压缩软件,大家往往想起老牌的 WinRAR.开源免费的 7-Zip.国产的快压.好压.360 压缩之类,甚至还有时代的眼泪 WinZip.一直以来,压缩软 ...

  7. Cosmetic Airless Bottles To Meet Practical Requirements

    Today, people use cosmetic bottles, many of which are in cosmetic airless bottles. We can use them, ...

  8. Spring IoC(一)bean实例化和依赖注入

    1.IoC容器概述 IoC 全称为 Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入. 所谓 IOC ,就 ...

  9. 吴裕雄 python 机器学习——数据预处理包裹式特征选取模型

    from sklearn.svm import LinearSVC from sklearn.datasets import load_iris from sklearn.feature_select ...

  10. 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号

    转载:https://www.cnblogs.com/tlduck/p/5132738.html #define _WIN32_DCOM #include<iostream> #inclu ...