我们把三种交换器讲解完毕了,我们再来看一下,如果使用RabbitMQ,实现松耦合设计,要讲松耦合,我们得先回到
就是为什么要使用RabbitMQ,解决什么问题,在这章节当中呢,分别给大家介绍了一下,我们用消息队列对我们系统的一个
优点,比如像同步变异步,还有解耦,这个解耦所展示的含义是什么呢,我如果对当前操作的服务增加了,你看我订单服务
原来操作短信服务,Email服务,Push服务,那现在我又新建一个微信服务,如果我们没有MQ系统,我们的消息队列接入的话,
回到我们传统的模型下,如果我这一块加了一个微信服务,那么也就意味着我现在,我的订单服务必须要代码修改,我原来在
订单服务当中,调用短信服务的接口,调用Email服务的接口,调用APP-Push服务的接口,现在我又加了一个微信服务,这块肯定
也好去调用微信服务的接口,那这样就不符合我们开闭的原则了,应该还知道吧,对于添加代码是开放的,但是对于修改代码
是关闭的,你不能去修改这里的东西,修改肯定会影响我们的健壮性的,对修改的部分做重新测试,所以说呢,我们现在要做的
是,通过MQ系统,去实现解耦和松耦合的设计,MQ系统接入以后,我们订单服务的消息,然后通过MQ系统,再将消息发送给不同的
服务平台,那么有新的服务介入了,只要让微信服务去订阅MQ里的消息就可以了,那么对于我订单服务来讲,没有任何的代码修改,
这就是解耦上的一个设计思路
来说一下解耦的实现,在这里我们还是以上一个案例,在这里我们要说明一下,一定要注意,对于服务与服务之间的解耦,
其实跟你用什么交换器没有关系,关键是你要入MQ系统,才能够解耦,明白我的意思吧,不要认为案例是拿fanout交换器
去写的,现在我想要来解耦的话,是不是得非用fanout,不是,direct,topic都可以实现解耦,它是都是MQ里面的交换器,
所以只要你在服务和服务之间使用MQ系统,或者消息队列,你就可以实现松耦合的设计,我只是做一个代码的实现而已,
先看这个图,这个需求,我原来有短信服务,有Push服务,现在我是不是加了一个红包服务,那么也就意味着,现在我要在我的
消息队列当中,让红包服务来订阅我MQ当中的消息,那我这里是不是得加一个队列,红包会去订阅这个队列
你看我们这个图是不是只要改Consumer就可以了,还需要动Provider吗,不用的,回到我们的Consumer当中,
首先我们的配置文件需要改一下,图中已经画的很清楚了,所以我这里还要给另一个队列起一个名
mq.config.queue.red=red
我们就叫read得了,我们现在给队列起个名称,然后接下来我们是不是要添加服务,叫RedReceiver,然后在这个服务当中,
我们要改的第一个是队列的名称,value="${mq.config.queue.red}",读我们properties文件里的这个配置
mq.config.queue.red=red
然后回过来,在这里fanout也不要动
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.red}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.FANOUT)
)
)
打印这里我们是不是得修改一下,接到消息以后,给用户发送10元红包
@RabbitHandler
public void process(String msg){
System.out.println("给用户发送10元红包........receiver: "+msg);
}
所以在整个编程过程当中,我并没有修改Provider的代码,我只是在Consumer添加了代码了,并没有去修改其他的class,
这个是搭建环境,第一个修改配置文件,第二个添加RedReceiver,然后接下来我们来测试一下,我们先把Consumer启动,
启动没有问题,我们接下来再去运行Provider,向他发送消息,观察控制台,我们可以看到,给用户发送10元红包的RedReceiver,
也运行了,他已经收到这个消息了,也是Hello RabbitMQ,我们只要对添加的新服务,去消息队列订阅我们的消息就可以,
所以这是一个典型的松耦合的设计,对于添加代码是开放的,对于修改代码是关闭的,我们主要是添加一个红包服务,来给
大家讲解一下,服务与服务之间用RabbitMQ以后,所带来一个松耦合的一个设计,这是非常灵活的
spring.application.name=rabbitmq-fanout-consumer
spring.rabbitmq.host=59.110.158.145
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
mq.config.exchange=order.fanout
mq.config.queue.sms=order.sms
mq.config.queue.push=order.push
mq.config.queue.red=red
package com.learn;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 消息接收者
* @author Administrator
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列的名称
* exchange:配置交换器
* key:路由键
*
* @Queue value:配置队列名称
* autoDelete:是否是一个可删除的临时队列
*
* @Exchange value:为交换器起个名称
* type:指定具体的交换器类型
*/
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.red}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.FANOUT)
)
)
public class RedReceiver {
/**
* 接收消息的方法。采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("给用户发送10元红包........receiver: "+msg);
}
}