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客户端,例如最多一次,至少一次,以及一 ...
随机推荐
- 【PAT甲级】1106 Lowest Price in Supply Chain (25分)
题意:输入一个正整数N(<=1e5),两个小数P和R,分别表示树的结点个数和商品原价以及每下探一层会涨幅的百分比.输出叶子结点深度最小的商品价格和深度最小的叶子结点个数. trick: 测试点1 ...
- BZOJ 3262: 陌上花开 (cdq分治,三维偏序)
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; c ...
- Python学习(四)—— 列表和元组的类中方法
列表 list:用中括号括起来,用“,”分割每个元素,列表中的元素可以是 数字.字符串.列表.布尔值......所有东西,可以说就是一个“集合” li = [1,3,5,'alex','age',[' ...
- 部署etcd中使用ansible进行变量初始化
ansible-playbook 要进行默认变量的生产,可以依靠jinja 的模板渲染功能 看几个官方给出的例子 调用setup 中的变量 例如 setup 中的变量层级为 ansible_eth0_ ...
- kettel路径配置
背景 kettel 8.3 jdk13.0.1 jre1.8.0 配置 PENTAHO_JAVA_HOME:C:\Program Files (x86)\Java\jre1.8.0_241 JAVA_ ...
- 【译】高级T-SQL进阶系列 (四)【上篇】:使用游标进行行级别处理
[译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 正常来说,使用游标并不是处理记录集的最佳方式.然而当一个经验丰富的程序员第一次开始写TSQL时,他们经常会寻找其 ...
- mui 监听 手机 物理返回键
mui.back = function(){ return //禁用物理返回键 也可以写其他逻辑 }
- unittest如何制作测试套件Testsuite 按method,class ,module,按命令行执行unittest
cmd 执行unittest case : python -m unitest test.py test2.py python -m unittest testfile.testclass.tes ...
- php redis 集群扩展类文件
<?php /** * redis集群驱动 */ namespace Common\Api; class RedisCluster{ protected $servers=array( '192 ...
- php 单机redis 常用命令
一.Redis连接与认证 //连接参数:ip.端口.连接超时时间,连接成功返回true,否则返回false $ret = $redis->connect('127.0.0.1', 6379, 3 ...