springboot集成rabbitMQ实战

基本概念请看另一篇:rabbitMQ入门

一、前期工作

1、引入依赖

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

2、application.yml文件添加相关配置

spring:
  rabbitmq:
    host: 192.168.1.60
    port: 5672
    username: guest
    password: guest

3、新增 RabbitMqConfig 配置类,先创建 ConnectionFactory 和 RabbitTemplate 的Bean

@Configuration
public class RabbitMqConfig {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${spring.rabbitmq.host}")
    private String host;
    @Value("${spring.rabbitmq.port}")
    private int port;
    @Value("${spring.rabbitmq.username}")
    private String username;
    @Value("${spring.rabbitmq.password}")
    private String password;

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setPublisherConfirms(true);
        connectionFactory.setPublisherReturns(true);
        return connectionFactory;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(){
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                logger.info("发送成功");
            }
        });
        template.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                logger.info("发送失败");
            }
        });
        return template;
    }

}

二、简单的用户下单模型范例

1、Queue、Exchange、Routing-key等信息配置到 application.yml文件

order:
  queue_name: order_queue_name
  exchange_name: order_exchange_name
  routing_key_name: order_routing_key_name

2、RabbitMqConfig 配置类增加订单消息队列相关配置

@Value("${order.queue_name}")
private String ORDER_QUEUE_NAME;
@Value("${order.exchange_name}")
private String ORDER_EXCHANGE_NAME;
@Value("${order.routing_key_name}")
private String ORDER_ROUTING_KEY_NAME;

@Bean
public DirectExchange orderExchange(){
	//创建持久化、非自动删除的交换器
	return new DirectExchange(ORDER_EXCHANGE_NAME,true,false);
}
@Bean
public Queue orderQueue(){
	//创建持久化的队列
	return new Queue(ORDER_QUEUE_NAME,true);
}
@Bean
public Binding orderBinging(){
	//通过路由将队列和交换器进行绑定
	return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(ORDER_ROUTING_KEY_NAME);
}

3、生产者

@Service
public class OrderServiceImpl implements OrderService{
    @Value("${order.queue_name}")
    private String ORDER_QUEUE_NAME;
    @Value("${order.exchange_name}")
    private String ORDER_EXCHANGE_NAME;
    @Value("${order.routing_key_name}")
    private String ORDER_ROUTING_KEY_NAME;

    @Autowired
    RabbitTemplate template;

    @Override
    public Order createOrder() {
        /**用户下单逻辑。。。。。。**/

        /**用户下单逻辑。。。。。。**/
        String content = "用户下单";
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        template.convertAndSend(ORDER_EXCHANGE_NAME,ORDER_ROUTING_KEY_NAME,content,correlationData);//消息通知
        return null;
    }
}

4、消费者

@Component
@RabbitListener(queues = "${order.queue_name}")
public class MqMsgListener {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @RabbitHandler
    public void orderQueue(String msg){
        logger.info("接收到的消息:" + msg);
    }
}

  

5、消费者的写法也可以换另一种

  • 在配置中增加并发量属性配置

spring:
  rabbitmq:
    listener:
      simple:
        # 消费者初始并发值
        concurrency: 5
        # 消费者最大并发值
        max-concurrency: 10
        # 某消费者一次监听可拉取的消息数
        prefetch: 3
  • 在 RabbitMqConfig 配置类中增加消息监听容器

@Value("${spring.rabbitmq.listener.simple.concurrency}")
private int concurrency;
@Value("${spring.rabbitmq.listener.simple.max-concurrency}")
private int max_concurrency;
@Value("${spring.rabbitmq.listener.simple.prefetch}")
private int prefetch;

@Bean
public SimpleMessageListenerContainer simpleMessageListenerContainer(){
	SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
	container.setQueues(orderQueue());//这里的参数可以支持多个队列,比如orderQueue(),productQueue()
	container.setExposeListenerChannel(true);
	container.setConcurrentConsumers(concurrency);//消费者初始并发值
	container.setMaxConcurrentConsumers(max_concurrency);//消费者最大并发值
	container.setPrefetchCount(prefetch);//某消费者一次监听可拉取的消息数
	container.setAcknowledgeMode(AcknowledgeMode.AUTO);//自动确认消息
	container.setMessageListener(new ChannelAwareMessageListener() {
		@Override
		public void onMessage(Message message, Channel channel) throws Exception {
			logger.info("第二种方式接收消息:" + new String(message.getBody()));
		}
	});
	return container;
}

  

6、消费者的写法还有另一种

  • 在配置中增加并发量属性配置同上

spring:
  rabbitmq:
    listener:
      simple:
        # 消费者初始并发值
        concurrency: 5
        # 消费者最大并发值
        max-concurrency: 10
        # 某消费者一次监听可拉取的消息数
        prefetch: 3
  • 在 RabbitMqConfig 配置类中增加

@Bean(name = "simpleRabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(){
	SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
	factory.setConnectionFactory(connectionFactory());
	factory.setConcurrentConsumers(concurrency);
	factory.setMaxConcurrentConsumers(max_concurrency);
	factory.setPrefetchCount(prefetch);
	factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
	return factory;
}
  •   消费者类

@Component
public class RabbitMqListener {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RabbitListener(queues = "${order.queue_name}",containerFactory = "simpleRabbitListenerContainerFactory")
    public void orderQueue(@Payload byte[] message){
        logger.info("第三种方式接收到的消息:" + new String(message));
    }
}

  

三、基于上面我们尝试一下 Fanout 广播模式(请忽视名称定义的不规范)

1、在 RabbitMqConfig 配置类中增加队列配置,这里交换器改用 fanout 模式

@Bean
public FanoutExchange fanoutExchange(){
	return new FanoutExchange(ORDER_EXCHANGE_NAME,true,false);
}
@Bean
public Queue orderQueue(){
	return new Queue(ORDER_QUEUE_NAME,true);
}
@Bean
public Queue orderQueue2(){
	//第二个队列名称自行定义,这里只是做一个示范
	return new Queue(ORDER_QUEUE_NAME2,true);
}
@Bean
public Binding orderBinging(){
	//将队列和交换器进行绑定,不需要路由,对个队列绑到同一个交换器
	return BindingBuilder.bind(orderQueue()).to(fanoutExchange());
}
@Bean
public Binding orderBinging2(){
	return BindingBuilder.bind(orderQueue2()).to(fanoutExchange());
}

2、生产者修改如下

@Override
public Order createOrder() {
	/**用户下单逻辑。。。。。。**/

	/**用户下单逻辑。。。。。。**/
	String content = "用户下单";
	template.convertAndSend(ORDER_EXCHANGE_NAME,"",content);//消息通知,这里不需要设置路由
	return null;
}

3、建立两个消费者查看结果

//第一个消费者
@Component
@RabbitListener(queues = "${order.queue_name}")
public class MqMsgListener {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @RabbitHandler
    public void orderQueue(String msg){
        logger.info("第一个队列接收到的消息:" + msg);
    }
}

//第二个消费者
@Component
@RabbitListener(queues = "${order.queue_name2}")
public class MqMsgListener2 {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @RabbitHandler
    public void orderQueue(String msg){
        logger.info("第二个队列接收到的消息:" + msg);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值