kafka生产者实例-精简可用

 不啰嗦,直接上代码(下面是个完整的生产者实例):

package com.z.kafka;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.slf4j.Logger;

public class ProducerUtil {
	
	private static ProducerUtil instance = null;
	private KafkaProducer<String, String> producer;
    public static final String SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer";
		
	public ProducerUtil() {
	    Properties props = new Properties();
	    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"127.0.0.1:9092");// 集群地址
	    props.put(ProducerConfig.ACKS_CONFIG, "all");// 请求被认为已完成的标准,all:响应阻塞完整提交。性能上不是最好的选择,但却是最稳的。
	    props.put(ProducerConfig.RETRIES_CONFIG, 1);// 失败尝试提交次数
	    props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);// 批量提交大小
	    props.put(ProducerConfig.LINGER_MS_CONFIG, 1);// 未成批等待提交毫秒数
	    props.put(ProducerConfig.CLIENT_ID_CONFIG, "client_test");// 发送客户端id身份标识,追查数据来源时比较有用。
	    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, SERIALIZER);// 序列化器
	    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, SERIALIZER);// 序列化器
	    // 客户端jar版本kafka-clients-0.11.0.1.jar
	    this.producer = new KafkaProducer<String, String>(props);
	  }
	
	  public static synchronized ProducerUtil getInstance() {
	    if (instance == null) {
	      instance = new ProducerUtil();
	      System.out.println("初始化 kafka producer...");
	    }
	    return instance;
	  }
	  
	  // 单条发送
	  public void send(ProducerRecord<String, String> msg) {
	    producer.send(msg);
	  }

	  public void send(List<ProducerRecord<String, String>> list) {
		
		for(int i = 0; i < list.size(); i++){
        	ProducerRecord<String, String> record = list.get(i);
        	producer.send(record);  		
		}
		System.out.println("batch send to kafka successfully! num: " + list.size());
        return;
	  } 
	  
	  public void shutdown() {
	    producer.close();
	  }

	  public static void main(String[] args) throws InterruptedException {
		  
		  ProducerUtil kafkaProducer = new ProducerUtil();
		  String topic = "test_topic";
		  int sendTimes = 1000;

		  long time0 = System.currentTimeMillis();
		  String msg = "";
		  List<ProducerRecord<String, String>> list = new ArrayList<ProducerRecord<String,String>>();
		  for(int i=1;i<=sendTimes;i++){
			  msg = "["+i+"]test message";
			  ProducerRecord<String, String> data = new ProducerRecord<String, String>(topic, msg);
			  kafkaProducer.send(data);
		  }
		  long cost0 = System.currentTimeMillis()-time0;// 发送耗时并不是那么精确,因为LINGER_MS_CONFIG
		  System.out.println("发送["+sendTimes+"]条,耗时:"+cost0+"ms.");
	  }
}

对以上生产者实例有几点需要说明:

1.生产者发送类为什么使用单例?

:这个在官方文档中可以找到“The producer is thread safe and sharing a single producer instance across threads will generally be faster than having multiple instances.” 翻译过来就是“生产者是线程安全的,跨线程共享单个生成器实例通常比拥有多个实例更快”。

2.有些项目需要计算发送数据的耗时,但是在上面实例中的计算方法不甚合适。

:由于LINGER_MS_CONFIG参数的设置,虽然我们调用了send方法,但只是把数据放入了缓冲区,至于有没有发送到对应的分区,还要参考LINGER_MS_CONFIG参数的设置。另外,就算LINGER_MS_CONFIG有设置,这个设置参数也不一定会不折不扣的执行,因为“Note that records that arrive close together in time will generally batch together even with linger.ms=0 so under heavy load batching will occur regardless of the linger configuration”,就是说,当负荷比较大的时候,生产者会强制批量发送。话说回来,怎么样才能精确知道发送数据的耗时呢?笔者目前也不知道^_^.

3.上面实例的版本

:完整jar包名称是 kafka-clients-0.11.0.1.jar(在这里提一下,网上可以见到很多的这种实例但是很少有人把自己代码依赖的jar包详细版本说明的,这一点很不好,因为不同版本之间是有差异的,即使是细微的差异也可能导致运行报错,可能会把初学者卡半天,浪费大家时间!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值