我们遇到了以下情况:
MessageChannel.send()
发送一条消息,生成一条记录,比方说,分区1 默认情况下,MessageChannel.send()
返回true
并且不会抛出任何异常,即使最终KafkaProducer无法成功发送消息。我们在此调用后约30秒观察日志中的以下消息:Expiring 10 record(s) for helloworld-topic-1 due to 30008 ms has passed since batch creation plus linger time
在我们的案例中,这是不可接受的,因为我们必须确保在调用MessageChannel.send()
时,所有消息最终都会传递给Kafka。
我们将spring.cloud.stream.kafka.bindings.<channelName>.producer.sync
打开到true
,这与文档描述的完全相同。它阻止了调用者,以便生产者确认交付成功或失败(MessageTimeoutException
,InterruptedException
,ExecutionException
),所有这些都由KafkaProducerMessageHandler
控制。这对我们来说似乎是最好的方法,因为在我们的案例中,性能影响可以忽略不计。
但是,如果抛出异常,我们是否需要自己重试? (在我们的客户端代码中,例如@Retryable
)
这是一个简单的实验项目:https://github.com/phdezann/spring-cloud-bus-kafka-helloworld
答案 0 :(得分:0)
如果在send()
线程上执行@StreamListener
并且异常被抛回绑定器,则绑定器重试配置将执行重试。
但是,由于您在HTTP线程上进行发送,因此您需要自己进行重试(在RetryTemplate()
范围内调用send)或使控制器方法@Retryable
。