1.生产者:在发送完消息后,收到回执确认。

主要是在SimpleProducer.java中修改了发送消息的2行代码,用到了回调函数,修改如下:

//发送消息
ProducerRecord<String, String> rec = new ProducerRecord<String, String>("test-topic","hello world from win7");
producer.send(rec,new Callback() {
public void onCompletion(RecordMetadata metadata,Exception exception) {
System.out.println("ack!!!");
}
}); //在发送消息后,收到回执确认。

完整代码如下:

 package cn.test.mykafka;

 import java.util.Properties;

 import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata; /**
* 简单生产者:在发送完消息后,收到回执确认。
*
*/ public class SimpleProducer2 { public static void main(String[] args) { //创建配置信息
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.42.133:9092"); //指定broker的节点和端口
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); //创建一个生产者
Producer<String, String> producer = new KafkaProducer<>(props); //发送消息
ProducerRecord<String, String> rec = new ProducerRecord<String, String>("test-topic","hello world from win7");
producer.send(rec,new Callback() {
public void onCompletion(RecordMetadata metadata,Exception exception) {
System.out.println("ack!!!");
}
}); //在发送消息后,收到回执确认。 //for (int i = 0; i < 10; i++)
// producer.send(new ProducerRecord<String, String>("test-topic", Integer.toString(i), Integer.toString(i))); //topic,key(非必填),value System.out.println("over");
producer.close();
}
}

SimpleProducer2.java

2.比较同步和异步生产者消息发送速度。

完整代码如下:

 package cn.test.mykafka;

 import java.util.Properties;

 import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata; /**
* 比较同步和异步生产者消息发送速度,参数未生效,失败
*
*/ public class SimpleProducer3 { static long starttime;
public static void main(String[] args) { //创建配置信息
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.42.133:9092"); //指定broker的节点和端口
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("producer.type", "async"); //sync为同步,async为异步,此配置未生效 //创建一个生产者
Producer<String, String> producer = new KafkaProducer<>(props); StringBuilder builder = new StringBuilder();
for( int i = 0 ; i < 100000 ; i++) {
builder.append(" " + i + ",");
} //发送消息
ProducerRecord<String, String> rec = new ProducerRecord<String, String>("test-topic",builder.toString());
producer.send(rec,new Callback() {
public void onCompletion(RecordMetadata metadata,Exception exception) {
System.out.println("receive ack : "+ (System.currentTimeMillis()-starttime) + "ms");
}
}); //在发送消息后,收到回执确认 starttime = System.currentTimeMillis();
System.out.println("over");
producer.close();
}
}

SimpleProducer3.java

kafka同步生产者:这个生产者写一条消息的时候,它就立马发送到某个分区去。follower还需要从leader拉取消息到本地,follower再向leader发送确认,leader再向客户端发送确认。由于这一套流程之后,客户端才能得到确认,所以很慢。
kafka异步生产者:这个生产者写一条消息的时候,先是写到某个缓冲区,这个缓冲区里的数据还没写到broker集群里的某个分区的时候,它就返回到client去了。虽然效率快,但是不能保证消息一定被发送出去了。

客户端向topic发送数据分为两种方式:
producer.type=sync 同步模式 
producer.type=async 异步模式

执行以上代码(通过控制producer.type参数取值sync/async)时,输出警告:

WARN org.apache.kafka.clients.producer.ProducerConfig - The configuration 'producer.type' was supplied but isn't a known config.

这说明producer.type参数配置根本没生效,后来我在官方文档中也没有找到这个参数,估计在kafka 2.0.0版本中此参数已经没有了。

于是乎,我在网上找了另一段代码(参考博客),修改后如下:

 package cn.test.mykafka;

 import java.util.Properties;
import java.util.concurrent.Future; import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata; /**
* 比较同步和异步生产者消息发送速度,有2个问题: 1.我不缺定starttime的取值位置是否正确? 2.时间差不多,没得出啥结论
*
*/ public class SimpleProducer4 { static long starttime; StringBuilder builder = new StringBuilder(); public void initBuilder() {
for (int i = 0; i < 100000; i++) {
builder.append(" " + i + ",");
}
} private Properties kafkaProps = new Properties(); /**
* 初始化一些配置信息
*/
public void initProperty() {
kafkaProps.put("bootstrap.servers", "192.168.42.133:9092"); // 指定broker的节点和端口
kafkaProps.put("acks", "all");
kafkaProps.put("retries", 0);
kafkaProps.put("batch.size", 16384);
kafkaProps.put("linger.ms", 1);
kafkaProps.put("buffer.memory", 33554432);
kafkaProps.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
kafkaProps.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
} /**
* 加载配置信息,生成一个生产者实例
*
* @param props
* @return
*/
public Producer<String, String> getProducer(Properties props) {
if (props == null || props.size() == 0)
throw new IllegalArgumentException();
return new KafkaProducer<>(props);
} /**
* 同步发送消息
*
* @param producer
* @throws Exception
*/
public void syncSend(Producer<String, String> producer) throws Exception { ProducerRecord<String, String> record = new ProducerRecord<String, String>("test-topic",
builder.toString() + "this is a sygn record"); // 同步发送消息,消息发送成功后,服务端会返回给一个RecordMetadata对象
Future<RecordMetadata> future = producer.send(record);
starttime = System.currentTimeMillis();
RecordMetadata metadata = future.get(); System.out.println("offset:" + metadata.offset() + "\npartition:" + metadata.partition() + "\ntopic:"
+ metadata.topic() + "\nserializedKeySize:" + metadata.serializedKeySize() + "\nserializedValueSize:"
+ metadata.serializedValueSize() + "\nreceive sygn ack : " + (System.currentTimeMillis() - starttime)
+ "ms" + "\n"); producer.close();
} /**
* 异步发送消息
*
* @param producer
*/
public void asyncSend(Producer<String, String> producer) { ProducerRecord<String, String> record = new ProducerRecord<String, String>("test-topic",
builder.toString() + "this is a asygn record"); producer.send(record, new Callback() {
public void onCompletion(RecordMetadata metadata, Exception e) {
System.out.println("offset:" + metadata.offset() + "\npartition:" + metadata.partition() + "\ntopic:"
+ metadata.topic() + "\nserializedKeySize:" + metadata.serializedKeySize()
+ "\nserializedValueSize:" + metadata.serializedValueSize() + "\n");
if (e == null) {
System.out.println("\nreceive asygn ack : " + (System.currentTimeMillis() - starttime) + "ms");
}
}
});
starttime = System.currentTimeMillis();
producer.close();
} public void start() throws Exception {
initBuilder();
initProperty();
// syncSend(getProducer(kafkaProps));
asyncSend(getProducer(kafkaProps)); } public static void main(String[] args) throws Exception { SimpleProducer4 myProducer = new SimpleProducer4();
myProducer.start();
}
}

SimpleProducer4.java

执行之后,发现同步和异执行时间差不多,没能证明异步比同步快。推测原因有2个:

1.消息太短,存在偶然性,看不出时间差;

2.我不确定这段代码是否正确?同步代码是否正确?异步代码是否正确?开始时间取值位置是否正确?

好吧,心好累。关于生产者的同步异步问题就先到这里吧,虽然结果不尽人意,但是过程中也学到了很多,以后有时间再继续吧。

PS:以上纯粹是我的探索测试,如果有不对的地方,欢迎留言指正,不胜感激。

kafka7 探索生产者同步or异步发送消息的更多相关文章

  1. ActiveMQ producer同步/异步发送消息

    http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式,可以通过代码配置: ((ActiveMQConnection)co ...

  2. Rocketmq异步发送消息

    package com.bfxy.rocketmq.quickstart; import java.util.List; import org.apache.rocketmq.client.excep ...

  3. 增加线程异步发送消息的方法二(Runnable)

    //获取当前时间:毫秒 long a = System.currentTimeMillis(); System.out.println("a :" + a); try { //更改 ...

  4. 增加线程异步发送消息的方法一(Thread)

    @RequestMapping(value="order/updateOrder.do") public String updateOrder(HttpServletRequest ...

  5. Flask入门邮件同步与异步发送(九)

    ​ 应用场景: 用户在注册或者密码丢失等过程中,账号绑定邮箱,用户在进行身份认证的过程中,电子邮箱确实是一种很常用的方式,Python中提供了smtplib可以实现发送电子邮件功能,Flask框架也有 ...

  6. java 中Handler 和Runnable 的使用 异步发送消息 转

    public class MainActivity extends Activity { TextView text1, text2; Button button; Thread th; @Overr ...

  7. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  8. ActiveMQ( 一) 同步,异步,阻塞 JMS 消息模型

    同步请求:浏览器 向服务器 发送一个登录请求,如果服务器 没有及时响应,则浏览器则会一直等待状态,直至服务器响应或者超时. 异步请求:浏览器 向服务器 发送一个登录请求,不管服务器是否立即响应,浏览器 ...

  9. kafka 生产者发送消息

    KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...

随机推荐

  1. Navicat(数据库可视化操作软件)安装、配置、测试

    Navicat(数据库可视化操作软件)安装.配置.测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.Navicat安装.激活与配置 4.简单测试 5.注意事项 6.相关博文 > ...

  2. js实现根据文本下标位置添加特殊标识

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. centos查看端口被哪个应用端口占用命令

    在linux一般使用netstat 来查看系统端口使用情况步. netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表.实际的网络连接以及每一个网络接口设备的      net ...

  4. Windows 10 Version 1803 (Updated March 2018) MSDN 镜像下载

    微软已按先前预期于美国时间 2018 年 4 月 30 日正式向所有用户发布了 Windows 10 Version 1803 (Updated March 2018) 的 ISO 镜像下载,按微软官 ...

  5. 【2019年03月29日】股票的滚动市盈率PE最低排名

    仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 深康佳A(SZ000016) - 滚动市盈率PE:2.51 - 滚动市净率PB:1.68 - 滚动年化股息收益率:2.9% - - - ...

  6. 高并发分布式系统中生成全局唯一(订单号)Id

    1.GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么通过组合的方式,保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合 ...

  7. python 多文件知识

    对于一个大型的项目,会存在很多个py文件,本文记录与多文件有关的内容. 1. python 如何在一个.py文件中调用另一个.py文件的类 如果是在同一个 module中(也就是同一个py 文件里), ...

  8. 八、Sql Server 基础培训《进度8-查询多种写法》(实际操作)

    知识点: 假设学生表.班级表.年级表 学生表(student) 内码 学生姓名 班级内码 001 张三 1002 002 李四 1002 003 王五 1003 004 钱六 1001 班级表(cla ...

  9. js实现十分钟内在页面无任何操作,页面跳转至登陆页

    // 如果10分钟没有操作,退出到登录页 var timer; function startTimer(){ clearTimeout(timer); timer=setTimeout(functio ...

  10. Spring AOP @AspectJ进阶

    @AspectJ可以使用切点函数定义切点,我们还可以使用逻辑运算符对切点进行复核运算得到复合的切点,为了在切面中重用切点,我们还可以对切点进行命名,以便在其他的地方引用定义过的切点.当一个连接点匹配多 ...