由于 kafka 没有对延迟消息可见性的隐式支持,我们必须手动实现它。
我正在尝试使用以下方法来实现它 -
delayInSeconds
和eventTime
,同时发送消息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();
}
timeToBeDelayed
为正,则暂停容器,等待持续时间并恢复容器 - 在同一线程上@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);
}
}
这一切正常,容器进入睡眠状态并根据上述逻辑恢复。但我有几个问题 -
谢谢!
答案 0 :(得分:1)
如果从监听线程调用pauseThenResumeAfter()
,则没有效果;在侦听器方法执行之前,容器实际上并未暂停。
您应该查看新的 2.7 功能 Non-blocking retries。
您应该能够重用它的一些基础设施来实现您的要求。