Spring kafka 用spring kafka实现延迟消息处理
由于kafka没有对延迟消息可视性的隐式支持,我们必须手动实现它 我正在尝试使用下面的方法来实现它-Spring kafka 用spring kafka实现延迟消息处理,spring-kafka,Spring Kafka,由于kafka没有对延迟消息可视性的隐式支持,我们必须手动实现它 我正在尝试使用下面的方法来实现它- 在发送消息时,在消息有效负载中添加delayUnseconds和eventTime字段 接收消息时,计算应处理消息的确切时间 根据上述值和现在,计算消费者必须等待的时间 如果timetobedayed为正值,则暂停container,等待持续时间并在同一线程上恢复容器 在resume调用之后,抛出一个异常,这将使SeektocurInterrorHandler重试消息处理。(如果未执行此操作,则
delayUnseconds
和eventTime
字段timetobedayed
为正值,则暂停container,等待持续时间并在同一线程上恢复容器谢谢 如果从侦听器线程调用
pauseThenResumeAfter()
,它将无效;在侦听器方法执行之前,容器实际上不会暂停
您应该看看新的2.7功能
您应该能够重用它的一些基础设施来实现您的需求
public class DelayedMessage {
String messageId;
Instant eventTime;
Long delayInSeconds;
}
private Instant getInstantWhenToBeProcessed() {
return eventTime.plus(delayInSeconds, ChronoUnit.SECONDS);
}
public long getTimeToBeDelayedInMillis() {
return Duration.between(Instant.now(), getInstantWhenToBeProcessed()).toMillis();
}
@Service
public class KafkaManager {
@Autowired
private KafkaListenerEndpointRegistry registry;
public void pauseThenResumeAfter(long delayInMillis) throws InterruptedException {
this.pause();
log.info("Sleeping current thread by: {}ms", delayInMillis);
Thread.sleep(delayInMillis);
log.info("Waking up the thread");
this.resume();
// Throw exception, so that SeekToCurrentErrorHandle does a seek and tries to re-process
throw new IllegalArgumentException("Failed to process record, as they instantToProcess has not yet arrived. Will retry after backoff");
}
public void pause() {
registry.getListenerContainers().forEach(MessageListenerContainer::pause);
}
public void resume() {
registry.getListenerContainers().forEach(MessageListenerContainer::resume);
}
}