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

消息队列模型——topic

基于SpringBoot的RabbitMQ入门实战(三)_第1张图片
生产者:发送消息;消费者:接收消息;队列:消息中转站
交换机:接受生产者发送的消息并将这些消息路由给服务器中的队列
交换机是有4种类型,这里用到的是topic,这种类型会根据路由键(routingKey)进行模糊匹配
这里对rabbitMQ的原理及作用不做赘述,只讲实战用例

在pom.xml中引入RabbitMQ依赖

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-amqpartifactId>
        dependency>

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

基于SpringBoot的RabbitMQ入门实战(三)_第2张图片

生产者(消息发送者)代码,可以看到图中有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条信息
基于SpringBoot的RabbitMQ入门实战(三)_第3张图片
不太明白的话,可以单独调用看看输出结果,单独调用一个send方法可以打印6条信息

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

基于SpringBoot的RabbitMQ入门实战(三)_第4张图片
基于SpringBoot的RabbitMQ入门实战(三)_第5张图片
基于SpringBoot的RabbitMQ入门实战(三)_第6张图片

若想继续了解RabbitMQ,可以看我的文章中基于SpringBoot的RabbitMQ入门实战(四)

你可能感兴趣的:(RabbitMQ实战)