消费者不满时,Kafka邮件就会丢失

时间:2019-02-18 18:10:55

标签: spring-boot apache-kafka kafka-consumer-api spring-cloud-stream

你好,我正在使用春季云流编写一个kafka消费者生产者。在我的使用者内部,我将数据保存到数据库中,如果数据库关闭,我将手动退出应用程序。重新启动应用程序后,如果数据库仍然关闭,则应用程序将再次停止。现在,如果我第三次重新启动应用程序,则在中间间隔(两次失败)中接收到的消息丢失了,kafka Consumer将获取最新消息,并且还会跳过退出代码的消息。

入站和出站通道活页夹接口

public interface EventChannel {

String inputEvent = "inputChannel";
String outputEvent = "outputChannel";

@Input(inputChannel)
SubscribableChannel consumeEvent();

@Output(outputEvent)
SubscribableChannel produceEvent();
}

服务类别-

1)生产者服务

@Service
@EnableBinding(EventChannel.class)

public class EventProducerService{

private final EventChannel eventChannel;

@Autowired  
public EventConsumerService(EventChannel eventChannel){
this.eventChannel = eventChannel;
}

public void postEvent(EventDTO event) {
    MessageChannel messageChannel = eventChannel.produceEvent();
    messageChannel.send(MessageBuilder
            .withPayload(event)
            .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
            .setHeader("partitionKey",event.getId().toString())
            .build());     
    }
}

2)消费者服务

@Component
@EnableBinding(EventChannel.class)
public class EventConsumerService{ 

private final ApplicationContext applicationContext;
private final EventChannel eventChannel;

@Autowired  
public EventConsumerService(ApplicationContext applicationContext,EventChannel eventChannel){
this.applicationContext = applicationContext;
this.eventChannel = eventChannel;
}

@StreamListener(EventChannel.inputEvent)
public void saveUpdateCassandra(EventDTO event){
  Event newEvent = new Event(event);
  try{
     eventRepository.save(newEvent)
    } catch(Exceptione e){
     e.printStackTrace();
     SpringApplication.exit(applicationContext,()-> 0); 
  }
}

应用程序属性文件

#Spring Cloud Streams Configuration
##Broker
spring.cloud.stream.kafka.binder.brokers=localhost:9092
##EventIngestion 
spring.cloud.stream.bindings.outputChannel.destination=Event
spring.cloud.stream.bindings.outputChannel.producer.partitionKeyExpression=headers.partitionKey
spring.cloud.stream.bindings.inputChannel.destination=Event
spring.cloud.stream.bindings.inputChannel.group=event-consumer-1
spring.cloud.stream.kafka.bindings.inputChannel.consumer.startOffset=earliest

这两个应用程序都独立运行,因此,如果我的数据库出现故障,使用者停止,则连续失败的消息就会丢失

1 个答案:

答案 0 :(得分:0)

首先,我不确定您对SpringApplication.exit(applicationContext,()-> 0);的期望是什么,但实际上,您正在关闭整个应用程序,而其中可能正在运行的一切。 其次,您的消息丢失是由于以下事实:Kafka活页夹绝对不知道发生了异常,因此必须将消息放回该主题。实际上,从活页夹的角度来看,由于您的代码,每条消息总是可以成功处理。所以。 。

请从您的StreamListener方法中删除try/catch,并传播异常,从而使活页夹知道存在错误。