rabbitmq企业开发实战2 -fanout

rabbitmq企业开发实战2

第二章 rabbitmq 发布订阅模式实战


场景

1. 异步通知
例如:用户在注册完后一般都会发送消息通知用户注册成功(失败)。如果在一个系统中,用户注册信息有邮箱、手机号,那么在注册完后会向邮箱和手机号都发送注册完成信息。利用MQ实现业务异步处理,如果是用工作队列的话,就会声明一个注册信息队列。注册完成之后生产者会向队列提交一条注册数据,消费者取出数据同时向邮箱以及手机号发送两条消息。但是实际上邮箱和手机号信息发送实际上是不同的业务逻辑,不应该放在一块处理。这个时候就可以利用发布/订阅模式将消息发送到转换机(EXCHANGE),声明两个不同的队列(邮箱、手机),并绑定到交换机。这样生产者只需要发布一次消息,两个队列都会接收到消息发给对应的消费者。

为什么这个场景要用这个模式?一次生产多端消费,简单模式一次生产,单端消费就没了
在这里插入图片描述


一、什么是发布/订阅模式(Publish/Subscribe)?

简单解释就是,可以将消息发送给不同类型的消费者。做到发布一次,消费多个。下图取自于官方网站(RabbitMQ)的发布/订阅模式的图例

在这里插入图片描述

P:消息的生产者

X:交换机

红色:队列

C1 (发送邮件),C2(发送短信):消息消费者

二、实战操作

1.定义fanout 交换机,定义两个队列,并将两个队列绑定到该交换机上

代码如下(示例):

package net.getbang.rabbitmq.fanout;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutBuildConfig {
    /**
     * 定义一个fanout 类型的交换机
     * @return
     */
    @Bean
    FanoutExchange testFanoutExchange(){
        return new FanoutExchange("fanout-test");
    }

    /**
     * 定义邮件发送队列
     */
    @Bean
    public Queue queueEmail(){
        return  new Queue("fanout.email");
    }
    /**
     * 定义短信发送队列
     */
    @Bean
    public Queue queueSms(){
        return  new Queue("fanout.sms");
    }

    /**
     * 将队列绑定到交换机上
     */
    @Bean
    Binding bindingExchangeMessage(@Qualifier("queueEmail")Queue queueMessage, FanoutExchange testFanoutExchange) {
        return BindingBuilder.bind(queueMessage).to(testFanoutExchange);
    }

    @Bean
    Binding bindingExchangeMessages(@Qualifier("queueSms")Queue queueMessages, FanoutExchange testFanoutExchange) {
        return BindingBuilder.bind(queueMessages).to(testFanoutExchange);
    }

}

比简单模式多了定义交换机以及绑定的两个操作。1

2.定义消费生产者

复制简单模式的消息生产者,在原来发送消息的方法中添加交换机的名字属性,添加后点击进去到方法

public void sendFanout(String exchangeName,String queueName, Object message){

    rabbitTemplate.setDefaultReceiveQueue(queueName);
    rabbitTemplate.convertAndSend(exchangeName,queueName,message);
}
@Override
public void convertAndSend(String exchange, String routingKey, final Object object) throws AmqpException {
	convertAndSend(exchange, routingKey, object, (CorrelationData) null);
}

发现这里已经中间不是队列的名称,而是routingKey 了,我们没有,所以暂时先空着,后续说明作用
代码如下(示例):

package net.getbang.rabbitmq.producer;


import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class FanoutProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendFanout(String exchangeName,Object message){

        rabbitTemplate.convertAndSend(exchangeName,"",message);
    }

}


消息消费

代码如下(示例):

package net.getbang.rabbitmq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class FanoutListener {

@RabbitListener(queues = "fanout.email")
public void reviceFanout(Object message){

    System.out.println("FanoutListener.reviceFanout 接收的消息:"+message);

    System.out.println("发送邮件");

}
@RabbitListener(queues = "fanout.sms")
public void reviceFanout2(Object message){

    System.out.println("FanoutListener.reviceFanout2 接收的消息:"+message);
    System.out.println("发送短信");
}

}

测试类代码测试发送消息

@Autowired
FanoutProducer fanoutProducer;
/**
 * fanout 模式发送消息测试
 */
@Test
public void sendFanoutMessage(){

    Map<String,String> messageBody =new HashMap(2);
    messageBody .put("会员id","66666");

    fanoutProducer.sendFanout("fanout-test",messageBody);

}
结果如下,达到目的

在这里插入图片描述
问题:上门发送消息中间空的routingkey 是什么场景下用的呢?
***斜体样式***代码位置:

源码链接: https://code.aliyun.com/411741962/rabbitmq-springboot.git
QQ群交流 671243328


  1. 注脚的解释 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海聊智造

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值