基于SpringBoot的RabbitMQ入门实战(三)

消息队列模型——topic

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200211223248449.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbmN5MF8wcw==,size_16,color_FFFFFF,t_70
生产者:发送消息;消费者:接收消息;队列:消息中转站
交换机:接受生产者发送的消息并将这些消息路由给服务器中的队列
交换机是有4种类型,这里用到的是topic,这种类型会根据路由键(routingKey)进行模糊匹配
这里对rabbitMQ的原理及作用不做赘述,只讲实战用例

在pom.xml中引入RabbitMQ依赖

        <!--rabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

为方便开发,把交换机,队列等配置到yml中。这里不配置路由Key,稍后再代码中写死

在这里插入图片描述

生产者(消息发送者)代码,可以看到图中有3个生产者,所以我们来创建三个生产者类

用户服务类
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * 生产者
 */
@Component
public class UserSender {
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Value("${mq.config.exchange}")
    private String exchange;
    /**
     * 发送消息的方法
     */
    public void  send(String msg){
        /**
         * convertAndSend
         * 参数一:交换机
         * 参数二:路由键 这里我们自己定义路由键
         * 参数三:消息
         * 我们每个生产者发送4种日志类型的消息,便于查看效果
         */
        this.amqpTemplate.convertAndSend(this.exchange,"user.log.info","user.log.info....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"user.log.debug","user.log.debug....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"user.log.error","user.log.error....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"user.log.warn","user.log.warn....."+msg);
    }
}
商品服务类
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * 生产者
 */
@Component
public class ProductSender {
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Value("${mq.config.exchange}")
    private String exchange;
    /**
     * 发送消息的方法
     */
    public void  send(String msg){
        /**
         * convertAndSend
         * 参数一:交换机
         * 参数二:路由键
         * 参数三:消息
         */
        this.amqpTemplate.convertAndSend(this.exchange,"product.log.info","product.log.info....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"product.log.debug","product.log.debug....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"product.log.error","product.log.error....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"product.log.warn","product.log.warn....."+msg);
    }
}
订单服务类
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * 生产者
 */
@Component
public class OrderSender {
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Value("${mq.config.exchange}")
    private String exchange;
    /**
     * 发送消息的方法
     */
    public void  send(String msg){
        /**
         * convertAndSend
         * 参数一:交换机
         * 参数二:路由键
         * 参数三:消息
         */
        this.amqpTemplate.convertAndSend(this.exchange,"order.log.info","order.log.info....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"order.log.debug","order.log.debug....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"order.log.error","order.log.error....."+msg);
        this.amqpTemplate.convertAndSend(this.exchange,"order.log.warn","order.log.warn....."+msg);
    }
}

消费者(消息接收者)代码,这里也对应图中应该创建3个消费者

info日志处理服务类
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 消费者(消息接收者)
 * @RabbitListener bindings:绑定队列
 * @QueueBinding value:绑定队列名称
 *               autoDelete:是否是一个可删除的临时队列
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = "${mq.config.queue_info_log}",autoDelete = "true"),
                //注意看这里,交换机的类型变成了 TOPIC
                exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
                //注意看这里,路由键设置成了通配符形式,*代表任意字符
                key = "*.log.info"
        )
)
public class InfosReceiver {
    @RabbitHandler
    public void  process(String msg){
        System.out.println("......Info.....Receiver:"+msg);
    }
}
error日志处理服务类
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 消费者(消息接收者)
 * @RabbitListener bindings:绑定队列
 * @QueueBinding value:绑定队列名称
 *               autoDelete:是否是一个可删除的临时队列
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = "${mq.config.queue_error_log}",autoDelete = "true"),
                 //注意看这里,交换机的类型变成了 TOPIC
                exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
                 //注意看这里,路由键设置成了通配符形式
                key = "*.log.error"
        )
)
public class ErrorsReceiver {
    @RabbitHandler
    public void  process(String msg){
        System.out.println("......Error.....Receiver:"+msg);
    }
}
全日志处理服务类
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 消费者(消息接收者)
 * @RabbitListener bindings:绑定队列
 * @QueueBinding value:绑定队列名称
 *               autoDelete:是否是一个可删除的临时队列
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = "${mq.config.queue_all_log}",autoDelete = "true"),
                //注意看这里,交换机的类型变成了 TOPIC
                exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
                //注意看这里,路由键设置成了通配符形式
                key = "*.log.*"
        )
)
public class AllReceiver {
    @RabbitHandler
    public void  process(String msg){
        System.out.println(".....All....Receiver:"+msg);
    }
}

测试代码

	//注入生产者类
    @Autowired
    private UserSender userSender;
    @Autowired
    private ProductSender productSender;
    @Autowired
    private OrderSender orderSender;
    @Test
    public void test3(){
        this.userSender.send("UserSender...");
        this.productSender.send("ProductSender...");
        this.orderSender.send("OrderSender...");
    }

执行测试代码输出结果

三个生产者向交换机发送了4条消息,交换机又根据不同的匹配规则向三个消费者发送消息,根据代码我们可以得出,控制台一共可以打印18条信息
在这里插入图片描述
不太明白的话,可以单独调用看看输出结果,单独调用一个send方法可以打印6条信息

登录RabbitMQ页面,可看到新创建出的交换机,队列以及交换机和队列绑定关系

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

若想继续了解RabbitMQ,可以看我的文章中基于SpringBoot的RabbitMQ入门实战(四)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值