RabbitMQ消息中间件

消息队列在使用过程中,面临着很多实际问题需要思考:

 消息从发送,到消费者接收,会经理多个过程:

 其中的每一步都可能导致消息丢失,常见的丢失原因包括:

  • 发送时丢失:

    • 生产者发送的消息未送达exchange

    • 消息到达exchange后未到达queue

  • MQ宕机,queue将消息丢失

  • consumer接收到消息后未消费就宕机

针对这些问题,RabbitMQ分别给出了解决方案:

  • 生产者确认机制

  • mq持久化

  • 消费者确认机制

  • 失败重试机制

 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。结果有两种请求:

  publisher-confirm,发送者确认

    消息成功投递到交换机,返回ack

    消息未投递到交换机,返回nack

  publisher-return,发送者回执

    消息投递到交换机了,但是没有路由到队列。返回ACK,及路由失败的原因。

 

 首先,修改publisher服务中的application.yml文件,添加下面的内容:

spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true
    template:
      mandatory: true

说明:

- `publish-confirm-type`:开启publisher-confirm,这里支持两种类型:
- `simple`:同步等待confirm结果,直到超时
- `correlated`:异步回调,定义ConfirmCallback,MQ返回结果时会回调这个ConfirmCallback
- `publish-returns`:开启publish-return功能,同样是基于callback机制,不过是定义ReturnCallback
- `template.mandatory`:定义消息路由失败时的策略。true,则调用ReturnCallback;false:则直接丢弃消息

测试交换机和队列:首先建好交换机名字,比如:amq.topic,然后再按下图操作点进去。

 在弹出的页面里面绑定队列名称,如下图:其中simple.#   代表以simple开头的队列都会匹配到。

 看生产者代码发布消息的时候是怎么操作的:

 但是我们发送消息的时候是需要确认机制的,因此我们还要有一个参数,作为消息的确认机制,这个参数就是:异步回调,这里我们以“correlationData”来命名,

correlationData这个对象获取future对象添加callback,callback里面有两个回调函数,一个是成功的回调,一个是失败的回调,如下图:

 由于它们都是接口里面的方法,因此可以采用匿名内部类的方式实现,同时这些接口也是函数式接口,因此可以采用lambda表达式简化。接着定义confirm机制和失败处理机制

 测试该接口,控制台如下输出:

 

 打开交换机监控页面:点击交换机,点开amq.topic

 

重新绑定一次,但是如果再绑定一次,其实它会报错,会提示access refused,这种情况说明是该用户下没有绑定该虚拟主机上的队列的权限,我们需要将虚拟主机添加给该用户:

 

 接下来我们看效果:

 所以当我们操作没有虚拟机所在权限的交换机或者队列时,就会报错误,比如我们将默认虚拟主机/这个给撤销了:我们把上图的再去掉clear就可以了,然后回到交换机页面,点击/所在的某个交换机名称,然后给它分配队列,我们会看到如下图:

 现在如果我们想恢复,直接将刚才clear那个再加回来就好了。接下来我们重新绑定一次就不会报权限拒绝的错误了。

 那为什么idea控制台还报错呢?

那是因为我们上面所演示的都是qw这个用户的,然后我们看下idea里面yam文件实际配置:

 那其实我在rabbit网页端分配的是这个:分配的是下图的最后一个,也就是说用下面这个amq.topic交换机绑定队列的话其实跟没设置一样,因为yam配置的是/,而不是默认虚拟主机这个的交换机(所以无论怎么绑定你会发现很奇怪,怎么明明绑定好了,控制台还路由不到),根据yaml配置文件,我们应该设置默认交换机这个,也即下图的第一个箭头标记的这个

 我们点开这个amq.topic,绑定好队列和队列标识就好了:

 再重新执行test测试下,控制台不报错了:

我们再测试下消息没有到达交换机的情况: 我们将交换机名称写错就可以测试了:

 我们再测下将路由表示写错:

总结:

 

posted @ 2023-06-27 18:28  xycccode  阅读(14)  评论(0编辑  收藏  举报