rabbitMq高级

1.保障消息成功投递到broker

  (a)第一步:在channel 上开启确认模式: channele.confirmSelect()

  (b)第二步:在channel 上添加监听: addConfirmListener, 监听成功和失败的返回结果,根据具体的结果在发送端对消息进行重新发送、或记录日志等后续处理!

  实例:https://blog.csdn.net/ctwy291314/article/details/80534604

  (c)第三步:还需要监听不可路由的消息(当前的exchange 不存在或者指定的路由key路由不到)时的情况。

  实例:https://blog.csdn.net/m0_37743948/article/details/82864452

 

2.rabbitMq怎么保证消息成功消费,有以下实现方式

  (a) 消息落库,延时补发:投放消息的同时,把消息序列化到DB中,如果投放成功了,则到DB中设置消息投放成功标识。投放失败则不管了。有另外线程扫描DB,获取没投放成功的消息重试投放,成功则修改投放成功标识到DB,重试n次后还是失败则设置投放失败标识到DB。该方案缺点是频繁DB操作,消耗资源严重,不适合高并发业务。

  (b)二次投递:抽象出一个消息重调服务,生产者发消息时发送两条,一条发送到消费者(即时发),一条发送到重调服务(延时几分钟后发)。当消费者接收到即时消息,成功消费后会立即发送成功消费消息到重调服务,重调服务保存成功消费记录。当重调服务受到延时的消息后,先到消费记录看该消息是否成功消费了,有则忽略,没有则推送消息到生产者,重新走一遍流程,直到消费成功为止(或者多少次后放弃该消息)。该方案DB操作少,适合高并发,但必须实现消息消费幂等性。

 

3.消费幂等性实现(消费多次效果=消费1次)

  (a)select + insert机制:先查询某些关键信息判断是否已经消费过,没有再进行消费。不适合高并发场景。

  (b)利用redis的原子性:redis是单线程的,新的值会取代旧的值,所以执行结果放redis里面。如果需要落地则可以异步落地,其他需要实时的系统对接数据可以直接对接redis。

 

4.消费限流策略:当队列内部堆积消息很多时,为了保证qos(服务质量),需要设定参数,保证不会有大量消息涌入消费端。

  (a)设置手动应答、一次推送几条消息到消费者

channel.basicQos(0, 1, false);// 一条一条处理

  (b)手动应答

channel.basicConsume(queueName, false, new MyConsumer(channel);// 手动签收

 

 5.TTL消息详解(消息生存时间)

  (a) RabbitMQ支持消息的过期时间,在消息发送时可以进行指定

  (b) RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过了队列的超时时间配置,那么消息会自动的清除。

 

6.保证消息不丢失

  (a) 消费失败时打印日志,后续通过日志补偿。(执行异常时有效)

  (b) 开启手动ack,长时间没有ack时消息重回队列。(服务器宕机时有效)

  (c)监听死信队列:没有ack但关闭了重回队列功能的消息、消息TTL过期、队列达到最大长度而抛弃的消息,会进度死信exchange(DLX)。

 

posted on 2019-06-27 17:23  javaGreenHand。。。  阅读(43)  评论(0)    收藏  举报