Apache kafka request.timeout.ms和Spring Kafka使用KafkaTemplate同步事件发布
对于配置通过SpringKafka同步发布的事件超时的最佳实践,我有点困惑。提供了一个示例,使用Apache kafka request.timeout.ms和Spring Kafka使用KafkaTemplate同步事件发布,apache-kafka,kafka-producer-api,spring-kafka,Apache Kafka,Kafka Producer Api,Spring Kafka,对于配置通过SpringKafka同步发布的事件超时的最佳实践,我有点困惑。提供了一个示例,使用ListenableFuture的get(SOME\u TIME,TimeUnit)启用事件的同步发布,超时时间为SOME\u TIME。(以下副本仅供参考) public void sendToKafka(最终MyOutputData数据){ 最终产品记录记录=createRecord(数据); 试一试{ template.send(record).get(10,TimeUnit.SECONDS);
ListenableFuture
的get(SOME\u TIME,TimeUnit)
启用事件的同步发布,超时时间为SOME\u TIME
。(以下副本仅供参考)
public void sendToKafka(最终MyOutputData数据){
最终产品记录记录=createRecord(数据);
试一试{
template.send(record).get(10,TimeUnit.SECONDS);
handleSuccess(数据);
}
捕获(执行例外){
handleFailure(数据、记录,例如getCause());
}
catch(TimeoutException | interruptedeexception e){
handleFailure(数据、记录、e);
}
}
另一方面,我看到Kafka有一个request.timeout.ms
的配置,它负责Kafka中的以下设置
配置控制客户端等待请求响应的最长时间。如果在超时时间过去之前未收到响应,则客户端将在必要时重新发送请求,或者在重试次数用尽时使请求失败
配置
模板.send(…).get(…)
的时间单位是否更有意义(例如,10秒/10000毫秒,如上面Spring Kafka的示例所示),或者更好的方法是配置请求.timeout.ms
(以及重试次数
)要在内部通过Kafka模拟这种行为,并对get()
?进行无参数调用,使用无参数get()
从来都不是一个好主意;如果客户端代码中有错误,您可能会永远挂起
这两个暂停时间真的不同
未来的get()
是获取发送的结果(成功或失败)
如果在get()
超时后生产者配置可以成功,那么您可以获得重复配置(假设您在失败后在应用程序级别重试)
我认为“最佳实践”是使用大于
retries*request.timeout.ms
的get()
超时,但这可能需要很长时间。但它将确保您获得发送的真实结果。在这种情况下获得超时应视为需要调查的异常情况。感谢您提供的信息!为了澄清一点,当你说“在get()
超时后,你可以得到重复的代码”时,你是指get()
超时一些时间重试*request.timeout.ms
(例如一些时间=1200ms,重试=2,request.timeout.ms=1000ms
)的场景吗?例如,在上述情况下,在第一次重试后,生产者重新发送发送(并且在某个时间成功t=1500ms>某个时间
),但在确认第二次发送成功之前,get()
调用的some\u时间
值生效并抛出一个TimeoutException
,导致以后重复?我的意思是,如果您在应用程序级别以及kafka客户端内重试(即,如果在get()
上获得超时,则再次调用send()
和get()
)。然后,是的,如果在get超时后在kafka客户端
级别重试发送成功,则应用程序级别的重试将导致重复发布。因此,最好确保get timeout大于retries*request.timeout.ms
。
public void sendToKafka(final MyOutputData data) {
final ProducerRecord<String, String> record = createRecord(data);
try {
template.send(record).get(10, TimeUnit.SECONDS);
handleSuccess(data);
}
catch (ExecutionException e) {
handleFailure(data, record, e.getCause());
}
catch (TimeoutException | InterruptedException e) {
handleFailure(data, record, e);
}
}