首页 » SEO优化 » phpkafka临盆同步技巧_Kafka面试问题2分娩消息是同步照样异步

phpkafka临盆同步技巧_Kafka面试问题2分娩消息是同步照样异步

访客 2024-12-11 0

扫一扫用手机浏览

文章目录 [+]

而异步是线程不去等待结果返回连续往下进行,而对结果的处理是通过一个回调方法去处理返回结果。
适宜数据同等哀求不高的场景。
这样的设计同等性虽然不高,但是吞吐量会得到提升。

大家可能奇怪发后既忘(fire-and-foget)是个什么东东呢?

phpkafka临盆同步技巧_Kafka面试问题2分娩消息是同步照样异步

发后即忘类似异步,差异是并没有异步处理结果的回调方法。
便是说只管发不管发送的结果如何,这种适宜发日志等不太主要的场景。
这样做提吞吐量是最高的。

phpkafka临盆同步技巧_Kafka面试问题2分娩消息是同步照样异步
(图片来自网络侵删)

下面对这三种发送办法在吞吐量和同等性上做了一个比较:

指标

同步发送

异步发送

发后即忘

吞吐量

最差

中等

最高

同等性

最好

中等

最差

kafka是若何实现的?

那么,kafka是若何实现上述发送办法的呢?

我们先看同步是怎么做的:

kafka同步发送的实现

KafkaProducer类 的send方法并非是void类型,而是Future类型,方法有2个重载方法,详细定义如下:

public Future send(ProducerRecord<k, V> record)

public Future send(ProducerRecord<k, v> record,Callback callback)

要实现同步的发送办法,可以利用返回的Future工具实现:

try{producer.send(record).get();} catch (ExecutionException | InterruptedException e){e.printStackTrace();}复制代码

实际上send)方法本身便是异步的,send)方法返回的Future工具可以使调用方稍后得到发送的结果。
示例中在实行send()方法之后直接链式调用了get()方法来壅塞等待 Kafka的相应直到发送成功,或者发生非常。
如果发生非常,那么就须要捕获非常并交由外层逻辑处理。

那么我们怎么能知道kafka做事端返回的相应呢?这时我们可以这么做:

可以在实行完send()方法之后不直接调用get()方法,比如下面的一种同步发送办法的实现

try(Future<RecordMetadata> future=producer.send(record);RecordMetadata metadata = future.get();System.out.println(metadata.topic() + "_" +metadata.partition() +":" + metadata.offset());}catch(excutionException | InterruptedException e){e.printStackTrace();}复制代码

metadata是返回的相应信息。
这样我们就可以根据返回相应的详细信息来做一些判断了。

kafka异步发送的实现

我们再来理解一下异步发送的办法,一样平常是在send()方法里指定一个Callback 的回调函数 Kafka 在返回相应时调用该函数来实现异步的发送确认。

Callback的办法非常洁明了,Kafka 有相应时就会回调。
发送成功,或抛出非常。
异步发送办法的示例如下

producer.send(record, new Callback() {@Overridepublie void onCompletion(RecordMetadata metadata, Exception exception) {if (exception != null)exception.printstackTrace();elsesystem.out.printIn(metadata.topic() + "_" +metadata.partition() +":" + metadata.offset());复制代码

示例代码中碰着非常时(exception!=null)只是做了大略的打印操作,在实际运用中该当利用更加稳妥的办法来处理,比如可以将非常记录以便日后剖析,也可以做一定的处理来进行重发。
onCompletion()方法的两个参数是互斥的,发送成功时,metadata不为null而 exception为null;发送非常时,metadata为null而exception 不为null。

producer.send(record1, callbackl);producer.send(record2,callback2);复制代码

对付同一个分区而言,如果record1于record2之前先发送(参考上面的示例代码),那么KafkaProducer 就可以担保对应的callback1在callback2之前调用,也便是说,回调函数的调用也可以担保分区有序。

kafka发后即忘的实现

实在很大略,如下所示:

try{producer.send(record);} catch (ExecutionException | InterruptedException e){e.printStackTrace();}复制代码

发了往后什么都不做就ok了,呵呵很大略吧,便是无法知道是否发送成功,由于根本不会处理做事真个相应。

写在末了

本人在掘金发布了小册,对上述功能如何实现做了源码级的阐发。

欢迎支持笔者的掘金小册:《Kafka 源码精讲》(请在稀土掘金网站或app中搜索干系课程)

标签:

相关文章