Spring Boot 整合 RabbitMQ 比较简单,引入 spring-boot-starter-amqp 就可以使用消息发送和接收功能。下面通过一个最简单的例子,先发送消息到队列,再加上消费者。

RabbitMQ 的安装可以看前面的 CentOS 7 安装配置 RabbitMQ。这里使用 Java 8 和 Spring Boot 1.5.10.RELEASE。

添加依赖和配置

创建 Maven 项目,pom.xml 如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>rabbitmq-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

额外增加 spring-boot-starter-web,是为了通过 HTTP 请求调用发送方法。

在 src/main/resources/application.yml 中配置 RabbitMQ 连接:

spring:
  rabbitmq:
    host: "<server-ip>"
    port: 5672
    username: "<username>"
    password: "<strong-password>"
    virtual-host: /

将地址、用户名和密码替换成实际值。这里连接的是 AMQP 端口 5672,不是管理页面的 15672;用户需要有 / 虚拟主机的权限,应用所在机器也要能访问这个端口。

配置队列

下面几个类都放在 src/main/java/com/example/demo 中。

创建 RabbitConfig:

package com.example.demo;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
    @Bean
    public Queue firstQueue() {
        return new Queue("firstQueue");
    }
}

这里使用默认交换器,只配置一个 firstQueue 队列。Queue 要导入 org.springframework.amqp.core.Queue,不要导成 java.util.Queue。

发送消息

创建生产者 Producer,通过 AmqpTemplate 发送消息:

package com.example.demo;

import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;

@Component
public class Producer {
    @Resource
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String message = "hello "
                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
        rabbitTemplate.convertAndSend("firstQueue", message);
    }
}

这个两参数的 convertAndSend 使用默认交换器,第一个参数是 routing key,第二个参数是消息内容。默认交换器会按队列名路由,所以这里的 routing key 写成 firstQueue。

为了方便调用,再创建 MessageController:

package com.example.demo;

import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {
    @Resource
    private Producer producer;

    @RequestMapping(value = "/send", method = RequestMethod.POST)
    public String send() {
        producer.send();
        return "sent";
    }
}

程序入口:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

先不加消费者,启动程序:

mvn spring-boot:run

再发送一条消息:

curl -X POST http://127.0.0.1:8080/send

请求返回 sent。打开 RabbitMQ 管理页面,在 Queues 中可以看到 firstQueue;没有消费者时,发送的消息会留在队列里,重复请求可以看到 Ready 数量增加。

消费消息

停止程序,加入 Consumer:

package com.example.demo;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "firstQueue")
public class Consumer {
    @RabbitHandler
    public void process(String message) throws InterruptedException {
        Thread.sleep(1000);
        System.out.println(message);
    }
}

@RabbitListener 指定监听的队列,@RabbitHandler 指定处理消息的方法。Spring Boot 已经自动配置了监听所需的组件,这里不用另外加 @EnableRabbit。

Thread.sleep(1000) 用来模拟处理消息时的耗时。重新启动程序后,控制台会大约每秒打印一条消息,队列中的积压消息也会逐渐被消费掉。

最后修改:2018 年 02 月 24 日
如果觉得我的文章对你有用,请随意赞赏