记一次线上Kafka数据丢失-消息send成功,所有消费者没有拉取到该消息

前提:kafka send成功

但是 消费者拉取的时候 并没有这条记录

1、工具:kafka tool

 

分析:

1、去服务器查看日志,发现有send成功的记录 ,但是没有Listener的记录

@Log4j2
@Component
public class RepaySuccessListener {

    @Autowired
    private OrderService orderService;

    @KafkaListener(topics = O2oDubboPostLoanProviderTopic.ORDER_CLEARED)
    public void repaySuccessListener(@Payload String value,
                                     @Header(KafkaHeaders.OFFSET) int offset,
                                     @Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) String key,
                                     @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition,
                                     @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        log.info("KafkaRepaySuccessConsumer: key:{} value:{} topic:{} partition:{} offset:{}", key, value,
                topic, partition, offset);
        JSONObject jsonObject = JSONObject.parseObject(value);
        String orderId = jsonObject.getString("orderId");

        if (StringUtils.isNotEmpty(orderId)) {
            orderService.repaySuccessHandle(Integer.valueOf(orderId));
        }
    }
}

2、利用kafka Tool 查看该数据在kafka是否有存储

记一次线上Kafka数据丢失-消息send成功,所有消费者没有拉取到该消息_第1张图片

 

稍加思索,初步判断应该是kafka在持久化数据的时候出问题了

3、系统有一个专门记录kafka发送失败的表,查看一下

果然从昨天开始报错了 :org.apache.kafka.common.errors.NotLeaderForPartitionException: This server is not the leader for that topic-partition.

kafka集群出问题了

4、结合以上分析 由于生产kafka配的ack = 1,即leader收到消息后即为发送成功,但是leader接收到消息后挂了,导致follower没有同步数据,所以消费者拉数据的时候 没有拉倒

 

对于这种问题

1、kafka的ack配置为-1 leader和所有follower都同步到才算发送成功,如果失败 则重发消息

2、可以用回调机制,业务上设置规则定时轮寻

你可能感兴趣的:(Kafka)