【本文内容】
- 通过
docker安装rabbitmq,并使用Spring Boot项目进行测试。 - 通过
Dockerfile安装rabbitmq_delayed_message_exchange插件实现延迟消息 - 通过
docker compose安装rabbitmq(以及delayed message插件),并同时启动Spring Boot项目进行测试。
【版本】
- docker version: v1.0.23
- docker compose version: v2.4.1
1. 官方镜像
我使用的是rabbitmq:3-management,详细镜像说明请查看:链接
rabbitmq:3和3-management区别是management版本会预先安装RabbitMQ management并启动。
2. 通过docker安装并启动rabbitmq
2.1 启动rabbitmq
docker run -d --name my-rabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost
-p 5672:5672 -p 15672:15672 rabbitmq:3-management
-d:后台运行--name:docker name-e RABBITMQ_DEFAULT_VHOST:声明rabbitmq的virtual host,默认为/-p:暴露port,5672为amqp协议端口,即程序连接rabbitmq的端口,15672为console界面的端口。
启动后查看:
2.2 Web Console界面
- 地址:http://localhost:15672/
- 默认的用户名密码:guest / guest
因为我们有设置自定义的vhost,可以看到已经创建了vhost=my_vhost:
2.3 通过Spring Boot程序验证
使用的是Spring Boot v2.7.0 + Spring Cloud Stream。 关于Spring Boot parent依赖:略 加上Spring Cloud Stream依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
<version>3.2.4</version>
</dependency>
application.properties中配置:
spring.rabbitmq.host=localhost
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=my_vhost
创建一个Consumer:
@Configuration
public class ConsumerConfig {
@Bean
public Consumer<String> helloConsumer() {
return message -> log.info("Received Message: {}", message);
}
}
启动后,我们在Console的exchange=helloConsumer-in-0中发布一条测试消息:
程序接收到消息:
3. 在docker中安装rabbitmq_delayed_message_exchange插件实现延迟消息
关于本地rabbitmq安装,详细查看文件:【RabbitMQ的那点事】利用rabbitmq_delayed_message_exchange插件实现延迟消息(超详细)
3.1 下载delayed message插件:
3.2 创建Dockerfile
目录:
Dockerfile文件:
FROM rabbitmq:3-management
COPY ./plugin/rabbitmq_delayed_message_exchange-3.11.1.ez /opt/rabbitmq/plugins/
RUN rabbitmq-plugins enable rabbitmq_delayed_message_exchange
3.3 build image
在Dockerfile文件所在目录build镜像:
docker build -t rabbitmq-with-plugin .
参数-t表示打上tag。
3.4 运行image
和#2.1的docker run命令相似,只不过把image换成我们自己的image:
docker run -d --name my-rabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost
-p 5672:5672 -p 15672:15672 rabbitmq-with-plugin:latest
3.5 测试
进入http://localhost:15672/#/exchanges,在新建exchange的选择中看到有type=x-delayed-message选项了。
依旧使用Spring Cloud Stream进行测试,关于delayed message在Stream中的配置,详细参考:cloud.spring.io/spring-clou…
创建一个Comsumer:
@Bean
public Consumer<String> helloDelayedConsumer() {
return message -> log.info("Received Delayed Message: {}", message);
}
application.yaml配置(其中helloConsumer方法是#2.3的测试):
spring.cloud.function.definition=helloConsumer;helloDelayedConsumer
spring.cloud.stream.rabbit.bindings.helloDelayedConsumer-in-0.consumer.delayed-exchange=true
写一个发送端代码:
@SpringBootTest
public class ProducerServiceTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void sendMessageToDelayedExchange() throws InterruptedException {
log.info("Start to send delayed message...");
rabbitTemplate.convertAndSend("helloDelayedConsumer-in-0", "#", "hello delayed message!", new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// 设置消息延迟时间,单位 ms
message.getMessageProperties().setHeader("x-delay", 20 * 1000);
return message;
}
});
log.info("Finished sending delayed message...");
Thread.sleep(40000L);
}
}
运行后log,可以看到消息在20秒后被送达:
2023-03-12 22:32:33.508 INFO 84955 --- [ main] com.config.ProducerServiceTest : Start to send delayed message... 2023-03-12 22:32:33.514 INFO 84955 --- [ main] com.config.ProducerServiceTest : Finished sending delayed message... 2023-03-12 22:32:53.540 INFO 84955 --- [vKkmI55vu0cAw-1] com.config.ConsumerConfig : Received Delayed Message: hello delayed message!
4. 通过Docker Compose安装
4.1 创建Spring Boot项目
application.properties文件,将rabbitmq配置换成从docker-compose.yml中读取,其它的配置参考上述#3.5:
spring.rabbitmq.host=${SPRING_RABBITMQ_HOST}
spring.rabbitmq.username=${SPRING_RABBITMQ_USERNAME}
spring.rabbitmq.password=${SPRING_RABBITMQ_PASSWORD}
spring.rabbitmq.port=${SPRING_RABBITMQ_PORT}
spring.rabbitmq.virtual-host=${SPRING_RABBITMQ_DEFAULT_VHOST}
依旧使用的是上述的两个Consumer测试,编写Controller用于测试:
@RestController
public class StreamBridgeController {
@Autowired
private StreamBridge streamBridge;
@Autowired
private RabbitTemplate rabbitTemplate;
@GetMapping("message")
public String sendMessage() {
streamBridge.send("helloConsumer-in-0", "hello consumer...");
return "success";
}
@GetMapping("delayed-message")
public String sendMessageToDelayedExchange() throws InterruptedException {
// 略,详细看#3.5测试用例
return "success";
}
}
项目pom.xml中,记得添加为可执行的jar:
<build>
<finalName>user-create-service</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
编写项目的Dockerfile:
FROM openjdk:17-alpine
COPY target/user-create-service.jar user-create-service.jar
expose 8085
ENTRYPOINT ["java","-jar","user-create-service.jar"]
4.2 编写docker-compose.yml
这里沿用了rabbit-docker中的Dockerfile,详细参考#3.2
version: "3.7"
services:
rabbit-test:
build:
context: ./rabbit-docker/
dockerfile: Dockerfile
image: rabbit-management:latest
container_name: rabbit-test
hostname: rabbit-host
networks:
- appnet
ports:
- "5672:5672"
- "15672:15672"
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
- RABBITMQ_DEFAULT_VHOST=test_vhost
volumes:
- rabbit-volume:/opt/rabbit/data
restart: always
user-create-service:
build: user-create-service/
image: user-create-service:latest
container_name: user-create-service
depends_on:
- rabbit-test
environment:
- SPRING_RABBITMQ_HOST=rabbit-host
- SPRING_RABBITMQ_USERNAME=guest
- SPRING_RABBITMQ_PASSWORD=guest
- SPRING_RABBITMQ_PORT=5672
- SPRING_RABBITMQ_DEFAULT_VHOST=test_vhost
networks:
- appnet
ports:
- "8085:8085"
restart: always
networks:
appnet:
driver: bridge
volumes:
rabbit-volume:
name: rabbit-volume
4.3 docker compose build/up
使用docker compose build来build镜像:
docker compose build
build好后使用docker compose up来启动:
docker compose up
本质上通过docker compose帮忙启动了两个container,一个是rabbitmq,一个是Spring Boot项目,所以也可以用docker ps查看正在运行的container。
4.4 测试
调用#4.1创建的两个API进行测试:
打印日志:
user-create-service | 2023-03-12 14:45:54.617 INFO 1 --- [nio-8085-exec-2] com.config.ConsumerConfig : Received Message: hello consumer...
user-create-service | 2023-03-12 14:46:02.255 INFO 1 --- [nio-8085-exec-1] com.web.StreamBridgeController : Start to send delayed message... user-create-service | 2023-03-12 14:46:02.263 INFO 1 --- [nio-8085-exec-1] com.web.StreamBridgeController : Finished sending delayed message... user-create-service | 2023-03-12 14:46:22.260 INFO 1 --- [dmwnKxEmjXUWg-1] com.config.ConsumerConfig : Received Delayed Message: hello delayed message!
4.5 docker compose stop/rm
- 通过
docker compose stop进行关闭。 - 通过
docker compose rm进行删除。