SpringBoot2.x 整合 RabbitMQ

1,398 阅读2分钟

SpringBoot 整合 RabbitMQ 非常方便,只需要两步

  1. 引入相关依赖
  2. 在 application.yml 中配置 RabbitMQ
  3. 通过打注解的方式,使用MQ

引入相关依赖

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

配置 RabbitMQ

# RabbitMQ 基本配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
# 虚拟主机,默认是/
spring.rabbitmq.virtual-host=/
# 超时时间,默认不超时,单位毫秒
spring.rabbitmq.connection-timeout=15000

发送MQ消息

最基本的使用

消息实体

/**
 * 订单的消息实体
 */
public class OrderMessage {

    private String id;

    private String name;

    public OrderMessage() {
    }

    public OrderMessage(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

发送消息

import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SendMessageService {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 通过 AmqpTemplate 发送消息
     */
    public void amqpSend(Object obj) {
        // 三个参数分别是 交换机名称 路由键 json化的消息实体
        String message = JSONObject.toJSONString(obj);
        amqpTemplate.convertAndSend("exchangeName", "routingKeyValue", message);
    }

    /**
     * 通过 RabbitTemplate 发送消息
     */
    public void rabbitSend(Object obj) {
        // 三个参数分别是 交换机名称 路由键 json化的消息实体
        String message = JSONObject.toJSONString(obj);
        rabbitTemplate.convertAndSend("exchangeName", "routingKeyValue", message);
    }
}

发送

import com.wqlm.rabbitmq.send.message.OrderMessage;
import com.wqlm.rabbitmq.send.service.SendMessageService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SendApplicationTests {

    @Autowired
    private SendMessageService service;

    @Test
    public void contextLoads() {
        OrderMessage orderMessage = new OrderMessage("123","订单123");
        service.amqpSend(orderMessage);
//        service.rabbitSend(orderMessage);
    }

}

消息的异步确认

上面的代码中,消息虽然发送出去了,但我们根本不知道消息是投递成功了还是投递失败了。实际开发中,为了保证消息的高可靠性投递,一般会采用 confirm 模式并进行异步确认

感兴趣的可以查看我写的另外两篇文章

RabbitMQ 之消息的可靠性投递

RabbitMQ confirm 模式之异步确认

消费 消息

最基本的使用

基础配置

# RabbitMQ 消费端配置
# 侦听器的最小线程数
spring.rabbitmq.listener.simple.concurrency=5
# 侦听器的最大线程数
spring.rabbitmq.listener.simple.max-concurrency=10
# 签收方式 auth:自动签收 manual:手动签收  NONE:不签收 推荐手动签收
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# 限流数,2表示每个监听器可以同时介绍2条数据
spring.rabbitmq.listener.simple.prefetch=2

监听器

import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * 消费消息
 * @author wqlm
 * @date 2019/8/25 10:34
 */
@Component
public class ConsumerMessageListener {
    /**
     * 监听指定队列
     * @RabbitListener 指定了 exchange 、key、Queue 后,如果 Rabbitmq 没有会去创建
     * @param message 消息体
     * @param headers 消息头
     * @param channel 通道
     * @return
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange("exchangeName"),
            key = "routingKeyValue",
            value = @Queue("queryName")
    ))
    public void listenerMessage(String message, @Headers Map<String,Object> headers, Channel channel)
            throws IOException {
        System.out.println(message);
        System.out.println(headers);
        //手动 ack
        channel.basicAck((Long)headers.get(AmqpHeaders.DELIVERY_TAG),false);
    }
}

项目地址

发送端 github.com/wqlm/rabbit…

消费端 github.com/wqlm/rabbit…