Kafka-JavaAPI(Producer And Consumer)
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)的更多相关文章
- Kafka客户端Producer与Consumer
Kafka客户端Producer与Consumer 一.pom.xml 二.相关配置文件 producer.properties log4j.properties base.properties 三. ...
- Kafka的Producer和Consumer源码学习
先解释下两个概念: high watermark (HW) 它表示已经被commited的最后一个message offset(所谓commited, 应该是ISR中所有replica都已写入),HW ...
- Kafka的Producer以及Consumer远程调用问题
公司需要分布式的JMS,所以研究了Kafka,之前在本地都没有出现问题,但是在服务器上布Kafka的时候发现了消费者无法消费的问题. kafka布到一台服务器上面,由于业务原因,producer和ka ...
- SpringBoot整合kafka(实现producer和consumer)
本文代码使用的是Spring Boot 2.1.8.RELEASE 版本 <parent> <groupId>org.springframework.boot</grou ...
- 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 ...
- [Kafka] - Kafka Java Producer代码实现
根据业务需要可以使用Kafka提供的Java Producer API进行产生数据,并将产生的数据发送到Kafka对应Topic的对应分区中,入口类为:Producer Kafka的Producer ...
- 057 Java中kafka的Producer程序实现
1.需要启动的服务 这里启动的端口是9092. bin/kafka-console-consumer.sh --topic beifeng --zookeeper linux-hadoop01.ibe ...
- springboot kafka集成(实现producer和consumer)
本文介绍如何在springboot项目中集成kafka收发message. 1.先解决依赖 springboot相关的依赖我们就不提了,和kafka相关的只依赖一个spring-kafka集成包 &l ...
- 如何创建Kafka客户端:Avro Producer和Consumer Client
1.目标 - Kafka客户端 在本文的Kafka客户端中,我们将学习如何使用Kafka API 创建Apache Kafka客户端.有几种方法可以创建Kafka客户端,例如最多一次,至少一次,以及一 ...
随机推荐
- 存储引擎:engine
1.表类型: 默认的服务器表类型,通过my.ini文件可以手动修改配置:default-storage- engine=INNODB 在创建表,或者编辑表时,可以指定表的存储引擎: 语法:engine ...
- 设备驱动基础学习--platform driver简单实现
platform是一条虚拟的总线.设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device drive ...
- Python - 装饰器实现缓存
from functools import wraps def cache(func): cache = {} @wraps(func) def wrap(*args): if args not in ...
- Bugku-CTF加密篇之这不是md5(666c61677b616537333538376261353662616566357d)
这不是md5 666c61677b616537333538376261353662616566357d
- 对象的上转型和下转型 (instanceof关键字)
1.对象的上转型,就是多态的一种写法 格式:父类名称 对象名 = new 子类名称(): Animal animal = new Cat(); 含义:右侧创建一个子类对象,把它当作父类来使用 向上转型 ...
- kettel路径配置
背景 kettel 8.3 jdk13.0.1 jre1.8.0 配置 PENTAHO_JAVA_HOME:C:\Program Files (x86)\Java\jre1.8.0_241 JAVA_ ...
- mysql成功的远程连接
1.在虚拟机上的window7中安装mysql,版本mysql-5.7.27-win32,可以是解压版或者是安装版的, MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果是msi ...
- hamming distance(汉明距离)
看knn算法时无意间发现这个算法,但是维基上有错误的示例和python代码...因为汉明距离并不是求相同长度字符串(或相同长度的整数)之间的字符(或数位)差异个数. 正确的详见:https://en. ...
- pycharm连接数据库报错Access denied for user 'root'@'localhost' (using password:YES),以及wampserver 2/3个服务器正在运行 问题
使用mysql版本为mysql5.7,参考下列 https://blog.csdn.net/qq_32969455/article/details/79051932 https://blog.csdn ...
- jQuery选择器的使用注意事项:
1. 选择其中含有特殊符号 W3C规范规定属性值中不能含有某些特殊字符,但在实际开发过程中,常遇到表达式中含有“#”或“.”等特殊字符的情况,如果按照普通的方式去处理就会出错,解决此类问题的方法就是使 ...