消息队列-不丢消息

检测消息丢失的方法
利用消息队列的有序性来验证是否有消息丢失。在 Producer 端,我们给每个发出的消息附加一个连续递递增的序号,然后在 Consumer 端来检查这个序号的连续性。
拦截器机制,在 Producer 发送消息之前的拦截器中将序号注入到消息中,在 Consumer 收到消息的拦截器中检测序号的连续性,消息检测的代码不会侵入到你的业务代码中,发消息的时候必须要指定分区,并且,在每个分区单独检测消息序号的连续性。如果你的系统中 Producer 是多实例的,也需要每个 Producer 分别生成各自的消息序号,并且需要附加上 Producer 的标识,在 Consumer 端按照每个 Producer 分别来检测序号的连续性。Consumer 实例的数量最好和分区数量一致,做到 Consumer 和分区一一对应,
在这里插入图片描述

  1. 生产阶段
    发送消息代码时,需要注意,正确处理返回值或者捕获异常,就可以保证这个阶段的消息不会丢失。以kafka为例
    同步发送时,只要注意捕获异常即可。
try {
    RecordMetadata metadata = producer.send(record).get();
    System.out.println(" 消息发送成功。");
} catch (Throwable e) {
    System.out.println(" 消息发送失败!");
    System.out.println(e);
}

异步发送时,则需要在回调方法里进行检查。

producer.send(record, (metadata, exception) -> {
    if (metadata != null) {
        System.out.println(" 消息发送成功。");
    } else {
        System.out.println(" 消息发送失败!");
        System.out.println(exception);
    }
});

  1. 存储阶段
    如果对消息的可靠性要求非常高,可以通过配置 Broker 参数来避免因为宕机丢消息。
    对于单个节点的 Broker,需要配置 Broker 参数,在收到消息后,将消息写入磁盘后再给 Producer 返回确认响应,默认7天
    如果是 Broker 是由多个节点组成的集群,需要将Broker 集群配置成:至少将消息发送到 2 个以上的节点,再给客户端回复发送确认响应。

  2. 消费阶段

不要在收到消息后就立即发送消费确认,而是应该在执行完所有消费业务逻辑之后,再发送消费确认。

以RabbitMQ为例

def callback(ch, method, properties, body):
    print(" [x] 收到消息 %r" % body)
    # 在这儿处理收到的消息
    database.save(body)
    print(" [x] 消费完成 ")
    # 完成消费业务逻辑后发送消费确认响应
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_consume(queue='hello', on_message_callback=callback)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值