开始

image.png

解决的问题就是消息真的被路由了吗?消息发给exchange路由到各个队列里面。如果exchange没有相应的路由规则,那么这条消息就被丢弃了。我们可以做一个特殊的设置,让exchange在路由消息的时候,如果没有找到对应的队列。可以不丢弃这条消息。将这条消息给返回回来。
image.png
如果exchange丢弃了这条消息的话。就会造成我们的订单业务异常,消息丢弃。
image.png
所以我们要使用消息返回机制。

image.png

大概讲解消息返回机制的原理。如果没有找到消息的队列会回调Return Listener方法,我们提前声明好这个方法就会被调用,里面我们可以写一些对消息没有被路由的异常的业务处理。
image.png

image.png

Mandatory有托管的意思。
image.png

代码实战

利用商家微服务来实现消息的返回机制。
ctrl+鼠标左键。
image.png
ctrl+鼠标左键
image.png
IDEA的左下方
image.png

image.png
第三个basicPublish 有个mandatory的参数。
image.png
用第二个就可以了
image.png
我们在原来的返回的方法里面加上mandatory参数 设置为true就可以了。开启了这个选项之后,我们的rabbitMQ在收到消息但是无法路由的时候,就会调用发送方的returnListener方法,
image.png

实现发送方的returnListener

加载channel上。
image.png
我们两个returnListener这两个方法都尝试一下,括号内要new一个returnListener
image.png

image.png
当我们发送的消息无法路由的时候,handleReturn会被调用,
image.png
调用的时候后面的这些参数会自动传递给我们。returnCode有点像Http的Code,是用一个数字 字码表示一个消息。路由的结果。 replyText是返回的信息,properties是消息的源数据,body就是消息的内容了。
image.png
如果这个log被打印出来就说明消息被返回回来了
image.png
大括号在log4j里面是占位符。
image.png

拼接参数,输出出来
image.png

body是字节数组,我们想看字符串。用String的构造方法就可以把字符串数组转成字符串了。
image.png
启动orderService和商家的微服务。用postman发送一个新订单的请求。试一下。
image.png

订单微服务在收到了订单 马上发消息给商家微服务
image.png
发送完消息后,他也收到了消息的发送端确认
image.png
切换到商家微服务。处理了消息了也把消息往回发了。我们要演示路由不了这个消息。
image.png
这是因为我们的消息路由成功了。我们在启动的时候就绑定了。
image.png
我故意让它路由不了
image.png
解绑,我们把这个队列的路由给他去掉。
image.png
解绑后。这样商家微服务再往回发的时候就找不到路由了。
image.png
再来发一个消息 试试
image.png
orderService没有收到商家回复的消息
image.png
我们再来看下商家的微服务。发完之后没有log
image.png
发送消息失败没有被路由,按说会调用handleReturn这个方法。
image.png
我们的事件是绑定在channel上的。如果这个channel被关了。 我们绑定这些属性、回调方法等都没有用。
image.png
我们的channel是在try里面声明的,
image.png
当他走出这个try快的时候就会自动的被关掉。这就叫做autoClosable
image.png

image.png
所以我们发送完消息,它就会被自动的关掉了。因为它走出了try块。那我们之前注册的returnListener就不管用了。
image.png
发送完消息 不让这个channel被关闭呢?一种是不要在try里面去声明channel
image.png
还有一种方法是。线程休眠1秒,这样try块就没走出来,那么这个channel就关不掉。我们的returnListener就可以被调用。
image.png
把这个异常声明一下
image.png
image.png
重启下 商家服务 测试

image.png
消息发送后没有被路由
image.png
返回的消息NoRoute
image.png
exchange和routingKey
image.png

最后是消息体的内容
image.png

另外一种returnListener

注释原来的代码
image.png

就一个handle方法。
image.png

image.png
看一下returnMessage类里面的属性。
image.png
通过对象可以get到各个属性
image.png
入参太多就可以换成对象的形式
image.png

重启服务测试

return了一个对象。这里输出的是对象的地址。
image.png

发送消息和回调不是一个线程。是异步的
image.png

结束