微服务架构-分布式消息中间件-083:SpringBoot整合RabbitMQ

1 简单回顾RabbitMQ为什么是高级队列

课题内容

  1. RabbitMQ交换机四种类型
  2. RabbitMQ路由键的作用
  3. RabbitMQ实现发布订阅队列
  4. SpringBoot整合RabbitMQ实现通讯
  5. RabbitMQ相关课程疑问解答

2 四种交换机类型与扇形交换机

RabbitMQ交换机类型
Direct exchange(直连交换机)
Fanout exchange(扇型交换机)
Topic exchange(主题交换机)
Headers exchange(头交换机)

交换机核心作用:分发路由消息、中转
队列:容器 存放多个不同消息 遵循先进先出的原则
消息:传递的参数
扇型交换机主要的特征:只要队列绑定同一个交换机,生产者将消息投递到交换机中,交换机会将消息发送给所有绑定的队列进行存放消息。

3 直连交换机类型设计原理

路由键:交换机根据路由键的值,发送不同的队列中 匹配过程
在这里插入图片描述
Direct exchange(直连交换机):根据生产者投递不同的路由键,交换机匹配路由键发送到具体的队列中存放消息。

4 通过代码形式演示直连交换机

在这里插入图片描述

public class ExProducer {
    private static final String QUEUE_NAME = "mayikt";
    /**
     * 定义交换机的名称
     */
    private static final String DIRECT_EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        System.out.println("生产者启动成功..");
        // 1.创建连接
        Connection connection = RabitMQConnection.getConnection();
        // 2.创建通道
        Channel channel = connection.createChannel();
        // 不需要关心队列,只关注交换机
        channel.exchangeDeclare(DIRECT_EXCHANGE_NAME, "direct", true);
        String routingKey = "mayikt.email";
        String msg = "生产者群发消息" + routingKey;
        channel.basicPublish(DIRECT_EXCHANGE_NAME, routingKey, null, msg.getBytes());
        channel.close();
        connection.close();
        // 如果交换机没有绑定队列,消息可能丢失
    }
}
public class EmailConsumer {
    /**
     * 定义短信队列
     */
    private static final String QUEUE_NAME = "consumer_direct_email";
    /**
     * 定义交换机的名称
     */
    private static final String DIRECT_EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("邮件消费者...");
        // 创建我们的连接
        Connection connection = RabitMQConnection.getConnection();
        // 创建我们通道
        final Channel channel = connection.createChannel();
        // 关联队列消费者关联队列
        channel.queueBind(QUEUE_NAME, DIRECT_EXCHANGE_NAME, "mayikt.email");
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println("邮件消费者获取消息:" + msg);
            }
        };
        // 开始监听消息 自动签收
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);

    }
}
public class SmsConsumer {
    /**
     * 定义短信队列
     */
    private static final String QUEUE_NAME = "consumer_direct_sms";
    /**
     * 定义交换机的名称
     */
    private static final String DIRECT_EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("短信消费者...");
        // 创建我们的连接
        Connection connection = RabitMQConnection.getConnection();
        // 创建我们通道
        final Channel channel = connection.createChannel();
        // 关联队列消费者关联队列
        channel.queueBind(QUEUE_NAME, DIRECT_EXCHANGE_NAME, "mayikt.sms");
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println("短信消费者获取消息:" + msg);
            }
        };
        // 开始监听消息 自动签收
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);

    }
}

运行结果:
在这里插入图片描述

5 主题交换机类型实现模糊匹配

在这里插入图片描述
当交换机类型为topic类型时,根据队列绑定的路由键模糊转发到具体的队列中存放。
#号表示支持匹配多个词;
*号表示只能匹配一个词
生产者:

channel.basicPublish(EXCHANGE_NAME, "mayikt.meite.sms", null, msg.getBytes());

消费者:

channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "mayikt.#");

6 SpringBoot整合Rabbitmq配置

SpringBoot整合RabbitMQ
Maven相关依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>
<dependencies>

    <!-- springboot-web组件 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 添加springboot对amqp的支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
    <!--fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.49</version>
    </dependency>
</dependencies>

项目核心配置类
application.yml配置

spring:
  rabbitmq:
    ####连接地址
    host: 127.0.0.1
    ####端口号
    port: 5672
    ####账号
    username: guest
    ####密码
    password: guest
    ### 地址
    virtual-host: /mayikt_rabbitmq

RabbitMQConfig

@Component
public class RabbitMQConfig {
    /**
     * springboot项目整合队列
     */
    /**
     * 定义交换机
     */
    private String EXCHANGE_SPRINGBOOT_NAME = "mayikt_springboot_exchange";
    /**
     * 短信队列
     */
    private String FANOUT_QUEUE_SMS = "mayikt_fanout_sms_queue";
    /**
     * 邮件队列
     */
    private String FANOUT_QUEUE_EMAIL = "mayikt_fanout_email_queue";

    /**
     * 声明sms队列
     *
     * @return
     */
    @Bean
    public Queue smsQueue() {
        return new Queue(FANOUT_QUEUE_SMS);
    }

    /**
     * 声明email队列
     *
     * @return
     */
    @Bean
    public Queue emailQueue() {
        return new Queue(FANOUT_QUEUE_EMAIL);
    }

    /**
     * 声明交换机
     *
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(EXCHANGE_SPRINGBOOT_NAME);
    }

    /**
     * 短信队列绑定交换机
     *
     * @param smsQueue 通过方法名字找到beanId,再找到对应队列
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding smsBindingExchange(Queue smsQueue, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(smsQueue).to(fanoutExchange);
    }

    /**
     * 邮件队列绑定交换机
     *
     * @param emailQueue
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding emailBindingExchange(Queue emailQueue, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(emailQueue).to(fanoutExchange);
    }
}

7 使用SpringBoot自动创建队列和交换机

生产者与消费者

@RestController
public class FanoutProducer {

    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 定义交换机
     */
    private String EXCHANGE_SPRINGBOOT_NAME = "mayikt_springboot_exchange";

    @RequestMapping("/sendMsg")
    public String sendMsg(String msg) {
        // 参数1 交换机名称、参数2路由key、参数3 消息内容
        amqpTemplate.convertAndSend(EXCHANGE_SPRINGBOOT_NAME, "", msg);
        // 投递消息,客户端不会立马知道消息是否被消费,能够确认知道是否投递到消息中间件
        // 可以根据消息全局Id主动查询 前端ajax
        return "success";
    }
}
@Component
@RabbitListener(queues = "mayikt_fanout_sms_queue")
public class FanoutSmsConsumer {

    /**
     * 监听队列回调的方法
     *
     * @param msg
     */
    @RabbitHandler
    public void process(String msg) {
        System.out.println("短信消费者消息msg:" + msg);
    }
}
@Component
@RabbitListener(queues = "mayikt_fanout_email_queue")
public class FanoutEmailConsumer {

    /**
     * 监听队列回调的方法
     *
     * @param msg
     */
    @RabbitHandler
    public void process(String msg) {
        System.out.println("邮件消费者消息msg:" + msg);
    }
}
@SpringBootApplication
public class SpringApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringApp.class);
    }
}

8 实现路由分发多个不同队列

运行结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值