数据库脱机时如何不丢失来自Kafka的消息

时间:2019-01-12 14:34:05

标签: java spring-boot apache-kafka microservices spring-kafka

我正在开发微服务,该服务使用来自Kaffka的消息,然后处理此消息并将输出存储到MongoDB

我是kafka的新手,丢失消息时遇到了一些问题。

场景非常简单:

如果mongoDB脱机,微服务会收到一条消息,然后尝试将输出保存到Mongo,那么我会收到错误消息,说mongo脱机,消息丢失了。

我的问题是在这种情况下,kafka中有任何机制可以停止发送消息。应该在Kafka中手动提交offset吗?在Kafka用户中处理错误的最佳实践是什么?

3 个答案:

答案 0 :(得分:1)

对于这种情况,您应该手动提交偏移量。仅当您的消息处理成功时才提交偏移量。您像下面这样提交。但是,您应该注意,消息具有ttl,因此消息在ttl过去后会自动从kafka代理中删除。

consumer.commitSync(); 

答案 1 :(得分:1)

我认为您应该使用Kafka Streams和Kafka Connect,而不是手动进行提交。管理两个系统之间的事务:Apache Kafka和MongoDB可能不那么容易,因此可以更好地使用已经开发和测试的工具(您可以了解有关Kafka Connect的更多信息:https://kafka.apache.org/documentation/#connecthttps://docs.confluent.io/current/connect/index.html

您的情况可能是这样的:

答案 2 :(得分:1)

'1.3.11'上使用pauseresume方法的一种方法(但是您必须使用spring kafka> 2.1.x)spring-kafka-docs

@KafkaListener生命周期管理

  

MessageListenerContainer注释创建的侦听器容器不是应用程序上下文中的bean。而是使用@KafkaListener类型的基础结构bean注册它们。该bean由框架自动声明,并管理容器的生命周期。它将自动启动将KafkaListenerEndpointRegistry设置为autoStartup的所有容器。

因此在应用程序中自动连线true注册表端点

KafkaListenerEndpointRegistry

从注册表spring-kafka-docs中获取@Autowired private KafkaListenerEndpointRegistry registry;

MessageListenerContainer
  

返回具有指定id的MessageListenerContainer;如果不存在这样的容器,则返回null。

参数:

  

id-容器的ID

public MessageListenerContainer getListenerContainer(java.lang.String id) 上,您可以使用MessageListenerContainerpause方法spring-kafka-docs

默认无效暂停()

  

在下一个poll()之前暂停此容器。

默认的无效简历()

  

在下一个poll()之后恢复该容器(如果已暂停)。