Rabbitmq 使用原理教程

Rabbitmq

适用场景:低耦合度场景、削峰、异步操作、调用端不强依赖于结果的使用场景

例如:

1:用户注册成功后发送 邮件,短信,移动锁屏通知等

2:商城秒杀活动,配合redis使用:
    1. redis存储商品库存,并在redis中设置每个用户每秒请求不得超过10次
    2. 用户在抢购时直接查询redis中的库存,之后判断库存是否大于0,并且每个用户只能抢购成功1次
    3. 之后将请求加入rabbitmq队列,

4. 消费者:
    1. 消费者拿到消息后再次查询redis,保证有库存
            无库存时给用户发送短信等,抢购失败。或者将状态存入redis,从redis中读取结果给用户发送抢购结果
    2. 预减redis中的库存
    3. 生成订单并插入
    4. 减少数据库中的库存

  1. 对用户发送抢购结果

1) 交换机类型

性能排序:fanout > direct > topic 比例大约为 11:10:6

其中还有header交换机,实际应用中较少,这里不做介绍

交换机类型 作用 描述
fanout 无路由交换机 直接与交换机exchange发生关联,不用routingKey
广播模式,一个消息进来时,投递到与该交换机绑定的所有队列
direct 直连交换机 需要绑定routingKey,完全根据绑定key进行投递,不支持模糊匹配
例如设置key 为order.key,那么投递或消费时必须使用 order.key
topic 匹配交换机 需要绑定routingKey,支持模糊匹配
*为模糊匹配,只匹配一个单词(order.test),#可以匹配多个单词 例如:order.test.test

概念说明

Broker:消息队列服务器实体

Exchange:消息交换机,他指定消息按什么规则,路由到哪个队列

Queue:消息队列载体,每个消息都会被投入到一个或多个队列

Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来

Routing Key:路由关键字,Exchange根据这个关键字进行消息投递

Vhost:虚拟主机,服务器中多个项目可使用不能虚拟主机,用于区分不同项目

producer:消息生产者

consumer:消息消费者

channel:消息信道,在客户端的每个链接里,可建立多个channel,每个channel代表一个会话任务

消息队列使用过程

客户端连接到消息队列服务器,打开一个channel

客户端声明一个Exchange,并设置相关属性

客户端声明一个Queue,并设置相关属性

客户端使用 Routing Key,在Exchange和Queue之间建立好绑定关系

客户端投递消息到 Exchange

exchange接收到消息后,就根据消息的Routing Key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里

死信队列

“死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃

以下操作会使消息进入死信队列

1.消息被拒绝,并且requeue被设置为false

2.消息过期

3.队列到达最大长度

用户普通下单逻辑

消费端消费消息时:慎用消息重新投递


当消息重新投递到消息队列时,这条消息不会回到队列尾部,仍是在队列头部

消费者会立刻消费这条消息,业务处理再抛出异常,消息再重新入队,如此反复进行


最好解决方法直接丢弃该消息,未处理的业务在定时任务中增加补偿机制。或者将消息直接确认,然后重新插入到队列,这样消息会自动插入到尾部,不会影响到其他消息

  1. 用户下单,数据库存储订单信息,数据库记录消息数据(消息状态为待确认模式)
  2. 生产者发送消息
  3. 建立发送消息确认机制 confirmCallback,消息从生产者(producer)发送消息到交换机(exchange),不论是否成功,都会执行确认回调方法
          (建议增加定时任务,处理db中状态为未处理的消息。此处ack为true时更新db中消息状态为成功。反之为false时,执行补偿机制或者不做任何处理,等待定时任务处理)

    4.建立投递队列失败回调机制 ReturnsCallback,exchange投递到队列失败 (退回模式),只有当入队列失败时才会执行
          (建议增加定时任务,处理db中状态为未处理的消息。执行补偿机制或者不做任何处理,等待定时任务处理)
  4. 消费者处理消息,查询数据库订单是否有误异常,如有异常丢弃该消息 (增加定时任务,对订单执行补偿机制)。之后处理订单状态或者其他操作逻辑… 处理完毕使用ack确认该消息。
          (处理业务逻辑时加入try catch,若出现catch直接丢弃该消息,等待定时任务处理)
  5. 定时任务,增加幂等性。每隔一段时间扫描消息表,处理待确认状态的消息。当定时任务尽最大努力尝试3次后依旧失败,将消息状态更改为处理失败。之后处理订单失败逻辑… 。或者增加定时任务每隔一段时间,处理失败的订单

你可能感兴趣的:(Rabbitmq,队列,java-rabbitmq,rabbitmq,redis)