Kafka 生产者消费者 API

1、Kafka 依赖

创建Maven工程,导入kafka依赖:

    <!--kafka-->
    <dependency>
      <groupId>org.apache.kafka</groupId>
      <artifactId>kafka-clients</artifactId>
      <version>0.11.0.2</version>
    </dependency>

2、Producer API:

package cn.xym.spark

import java.util.Properties

import org.apache.kafka.clients.producer.{
    
    KafkaProducer, ProducerRecord}

object Kafka {
    
    
  def main(args: Array[String]): Unit = {
    
    
    // 创建配置
    val props = new Properties()
    // 设置Kafka集群
    props.put("bootstrap.servers", "chust01:9092")
    // 设置ack
    // 0: 不需要leader partition确认接收成功, 将消息发送到leader partition即可
    // 1:需要等待leader partition确认接收成功
    // -1(all): 需要等待leader partition以及ISR列表中的follower都确认接收成功
    props.put("acks", "all")
    // 设置key和value的序列化
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")

    // 创建一个Kafka的生产者
    val producer = new KafkaProducer[String,String](props)
    for (elem <- 1 to 100) {
    
    
    // 发送消息 三个参数: ①topic, ②key, ③value
    producer.send(new ProducerRecord[String,String]("test","1001","zhangsan"))
    Thread.sleep(10000)
    }
    // 关闭资源
    producer.close()
  }
}
参数名称 说明 默认值
bootstrap.servers kafka集群的broker-list
acks 确保生产者可靠性设置acks=0:不等待成功返回acks=1:等Leader写成功返回acks=all:等Leader和所有ISR中的Follower写成功返回,all也可以用-1代替 -1
key.serializer key的序列化器
value.serializer value的序列化器
retries 发送失败尝试重发次数 0
batch.size 每个partition的未发送消息大小 16384
partitioner.class 分区类,可以自定义分区类,实现partitioner接口 默认是哈希值%partitions
max.block.ms 最大阻塞时长 60000

3、Consumer API

package cn.xym.spark

import java.util.Properties

import org.apache.kafka.clients.consumer.KafkaConsumer

object KafkaConsumer{
    
    
  def main(args: Array[String]): Unit = {
    
    
    import org.apache.kafka.clients.consumer.ConsumerRecord
    import org.apache.kafka.clients.consumer.ConsumerRecords
    import java.util
    //创建一个配置
    val props = new Properties()
    //配置Kafka集群的ip和端口号
    props.put("bootstrap.servers", "chust01:9092")
    //设置消费者组的id,如果有多个相同id的消费者程序,那么他们将在一个组中
    props.put("group.id", "testGroup1")
    //开启自动提交,默认是开启
    props.put("enable.auto.commit", "true") //默认值true
    //默认每隔5000ms提交一次
    props.put("auto.commit.interval.ms", "1000") //默认值5000
    //key和value的序列化
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    //创建一个Consumer客户端
    val consumer = new KafkaConsumer[String,String](props)
    //consumer消费
    val topics = new util.ArrayList[String]()
    topics.add("test")
    consumer.subscribe(topics)
    //为了能够一直从Kafka中消费数据,使用while死循环
    while (true){
    
    
      //拉取数据,kafka推过来的一堆数据
      val records = consumer.poll(1000)
      //对这些数据转化为迭代器进行遍历输出
      val iter = records.iterator()
      while (iter.hasNext){
    
    
        val next = iter.next()
        println(s"partition = ${next.partition()},offset = ${next.offset()},value = ${next.key()},value = ${next.value()}")
      }
    }


  }
}

4、Consumer Offset API 偏移

package cn.xym.spark

import java.util
import java.util.Properties

import org.apache.kafka.clients.consumer.{
    
    ConsumerRecord, ConsumerRecords, KafkaConsumer}

object KafkaConsumer2 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    // 创建一个配置
    val props = new Properties()
    // 配置Kafka集群的ip和端口号
    props.put("bootstrap.servers", "chust01:9092")
    // 设置消费者组的id, 如果有多个相同id的消费者程序, 那么他们将在一个组当中
    props.put("group.id", "testGroup1")
    // 关闭自动提交[默认就是开启]
    props.put("enable.auto.commit", "false")
    // key和value的反序列化
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    // 创建一个Consumer客户端
    val consumer = new KafkaConsumer[String, String](props)
    // consumer消费
    val topics = new util.ArrayList[String]()
    topics.add("test")
    // 订阅topic
    consumer.subscribe(topics)
    // 创建一个集合, 用来存放消息的个数
    val buffer = new util.ArrayList[ConsumerRecord[String, String]]()
    // 为了能够一直从Kafka中消费数据, 使用 while true 死循环
    while (true) {
    
    
      // 设置超时时间, 单位是毫秒, 返回一些条数据
      val records: ConsumerRecords[String, String] = consumer.poll(1000)
      // 对这些数据进行遍历输出
      val iter: util.Iterator[ConsumerRecord[String, String]] = records.iterator()
      while (iter.hasNext) {
    
    
        val next: ConsumerRecord[String, String] = iter.next()
        println(s"partition = ${next.partition()}, offset=${next.offset()}\nkey = ${next.key()}, value = ${next.value()}")
        buffer.add(next)
      }
      if(buffer.size()>5){
    
    
        // 手动提交offset有两种, 一种是同步阻塞方式, 一种是异步非阻塞方式
        consumer.commitAsync()
        // consumer.commitSync()
        buffer.clear()
      }

    }
  }
}

猜你喜欢

转载自blog.csdn.net/xiaoxaoyu/article/details/112855417