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. Java - Test - TestNG: testng.xml 元素 class

    Java - Test - TestNG: testng.xml 元素 class 1. 概述 class 相关的元素 classes class methods exclude include 2. ...

  2. 安装Tengine版本的nginx

    安装tengine版nginx #!/bin/bash yum install epel-release -y yum install gcc unzip gcc-c++ git wget bind- ...

  3. 存储引擎:engine

    1.表类型: 默认的服务器表类型,通过my.ini文件可以手动修改配置:default-storage- engine=INNODB 在创建表,或者编辑表时,可以指定表的存储引擎: 语法:engine ...

  4. PHP基础学习笔记5

    一.连接MYSQL 1.1 MySQLi - 面向对象 <?php $servername = "localhost"; $username = "username ...

  5. Linux上临时路由、永久路由配置

    Linux下查看路由条目 查看路由表命令 route -n 示例 [root@cobbler_vm ~]# route -n Kernel IP routing table Destination G ...

  6. 吴裕雄 PYTHON 人工智能——智能医疗系统后台智能分诊模块及系统健康养生公告简约版代码展示

    #coding:utf-8 import sys import cx_Oracle import numpy as np import pandas as pd import tensorflow a ...

  7. 蚁人cp数

    可怜的蚁人进入量子领域后,黄蜂女被灭霸的一个响指带走,导致可怜的蚁人困在了量子领域,为了生存,他们开始建造自己家园. 蚁人为了方便在这里生存,他们建造了自己火车站.某车站有N个人上车,其中M对是情侣, ...

  8. 【C语言】字符数组,碎碎念

      存储方法: (1)字符数组赋值 ①初始化 ]={"China'} 或 ]="China' 注意:字符串可以不加{},单字符必须加 ]={,,} ②键盘输入 () char a; ...

  9. 将.NET Core Web Api发布到Linux(CentOS 7 64)

    将.NET Core(2.1) Web Api发布到Linux(CentOS 7 64) 近来在学习linux相关的一些东西,然后正巧想试一下把core的应用程序发布到Linux,毕竟跨平台.尝试一下 ...

  10. sockfd_to_family函数

    #include <sys/socket.h> #include <netinet/in.h> #define SA struct sockaddr int sockfd_to ...