Docker Compose 从入门到实践
Docker Compose介绍
什么是 Docker Compose
Docker Compose 是 Docker 官方提供的一个工具,用于 定义和管理多容器应用。通过一个配置文件(通常是 docker-compose.yml
),你可以同时启动、停止和管理多个 Docker 容器,并处理它们之间的网络、数据卷和依赖关系。
为什么需要 Docker Compose
在实际开发中,很多应用不只是单一容器,而是由多个服务组成。例如,一个典型的 Web 应用可能包含:
-
数据库(MySQL / Redis)
-
消息队列(RabbitMQ / Kafka)
-
Web 服务(Spring Boot / Node.js)
如果每个服务都用 docker run
单独启动,需要手动管理网络、端口和依赖,非常繁琐。
Docker Compose 的工作方式
-
编写
docker-compose.yml
文件,定义所有服务及其配置 -
执行
docker compose up
,Docker Compose 会:-
拉取镜像(如果本地不存在)
-
创建网络和卷
-
启动容器并按依赖顺序运行
-
-
容器停止或删除时,只需执行
docker compose down
优势
-
一条命令管理多容器:只需
docker compose up
就能启动所有服务 -
服务依赖控制:通过
depends_on
设置启动顺序 -
统一配置:网络、端口映射、数据卷、环境变量都可以在一个文件里管理
-
便于开发和测试:开发者可以快速启动完整的应用环境
Docker Compose模板指令
images
在 Docker Compose 中,images
不是一个直接使用的指令,而是通过 image
指令来指定要使用的镜像名称。在 Docker Compose 配置文件(docker-compose.yml
)中,image
是用来定义服务所使用的 Docker 镜像的。
services:service_name:image: <image_name>:<tag># 其他配置项
-
image
:指定要使用的镜像,格式为:<image_name>:<tag>
。-
<image_name>
:镜像的名称。 -
<tag>
:镜像的标签,通常为latest
,或者指定某个版本号。
-
-
如果指定了
image
,Docker Compose 会尝试从本地查找该镜像。如果镜像不存在,Docker 会自动拉取它。
例:
services:web:image: nginx:latest # 使用官方 nginx 镜像,版本是 latestports:- "8080:80"
version: '3.8'services:app:image: myregistry.com/myapp:v1 # 从指定的 Docker 仓库拉取镜像ports:- "3000:3000"
ports
在 Docker Compose 中,ports
用于将容器内的端口映射到宿主机的端口。这使得你可以从外部访问容器内运行的应用程序。
-
宿主机的端口(如
8080
)是暴露给外部(比如浏览器)的端口,允许外部访问。宿主机的端口(即暴露给外部的端口)可以灵活指定 -
容器内的端口(如
80
)是服务实际监听的端口,这个端口不会改变,只是通过ports
配置映射到宿主机的端口。容器的端口(即容器内部服务的监听端口)通常是 固定的,默认不可变,但有一些特殊情况可以修改容器内服务的监听端口
services:web:image: nginxports:- "8080:80" # 宿主机 8080 端口映射到容器 80 端口- "8443:443" # 宿主机 8443 端口映射到容器 443 端口
可以让 Docker 自动选择宿主机的端口,通常适用于测试或开发环境,容器的端口会映射到宿主机的一个随机端口。
services:web:images: nginxport:- "8080" # 自动映射容器的 80 端口到宿主机的随机端口
有时你需要将多个端口映射到宿主机上的一系列端口,可以使用端口范围来进行映射。
services:app:image: myappports:- "5000-5010:5000-5010" # 宿主机的 5000 到 5010 端口映射到容器的 5000 到 5010 端口
也可以指定宿主机的 IP 地址进行端口映射,这样容器的端口只会在特定的 IP 地址上暴露。
services:web:image: nginxports:- "127.0.0.1:8080:80" # 只允许通过 localhost 访问容器的 80 端口
volumes
在 Docker 中,Volumes(卷)是用于持久化和共享容器数据的一种机制。容器的文件系统是临时的,当容器停止或删除时,容器内的数据会丢失。为了避免这种情况,Docker 提供了 卷(Volumes),用于将数据保存在宿主机或其他地方,并使其能够在容器生命周期之间保持持久性。
services:app:image:myappvolumes:- mydata:/data #将名为mydata的卷挂载到容器的 /data目录下
volumes:mydata: #定义一个命名卷
在 docker-compose.yml
中,你也可以在 volumes
字段下定义和管理卷,使其在多个服务之间共享。
services:web:image: nginxvolumes:- web-data:/usr/share/nginx/html # 将名为 web-data 的卷挂载到 nginx 服务的 /usr/share/nginx/html 目录app:image: node-appvolumes:- web-data:/app/data # 将名为 web-data 的卷挂载到 app 服务的 /app/data 目录volumes:web-data: # 共享卷
使用 Bind Mount (绑定挂载)进行数据同步:将宿主机的目录直接挂载到容器内,任何对宿主机目录的修改都会立刻反映到容器内
services:web:image: myappvolumes:- ./data:/app/data # 宿主机的 ./data 目录挂载到容器的 /app/data 目录- ./config:/app/config # 宿主机的 ./config 目录挂载到容器的 /app/config 目录
命名卷vs绑定挂载
-
命名卷(Named Volumes) 使得容器和数据解耦,容器删除后数据依然保留,适合持久化数据和容器之间共享数据。
-
Bind Mount(绑定挂载) 则直接依赖于宿主机的目录,容器删除后,挂载关系不再存在,但宿主机的数据会保留。
特性 | 命名卷(Named Volumes) | 绑定挂载(Bind Mounts) |
---|---|---|
容器删除后数据是否保留? | 数据会保留,卷依然存在,并可以挂载到新的容器上 | 容器删除后挂载关系丢失,但宿主机上的目录保留数据 |
数据存储位置 | 由 Docker 管理,存储在 Docker 特定的路径(如 /var/lib/docker/volumes/ ) | 存储在宿主机指定的目录路径下 |
访问数据的方式 | 通过挂载卷到容器,容器之间可以共享数据 | 通过挂载宿主机的目录到容器,容器内的数据直接映射到宿主机目录 |
数据持久化 | 容器删除后数据持久化,卷中的数据可以重新挂载 | 数据会保留在宿主机目录中,但容器删除后挂载关系不再有效 |
适用场景 | 适用于生产环境、容器间共享数据、需要持久化的场景 | 适用于开发环境、需要实时同步宿主机和容器数据的场景 |
查看和管理卷的数据
列出所有卷:
docker volume ls
查看卷的详细信息:
docker volume inspect <volume-name>
删除卷:
docker volume rm <volume-name>
networks
在 Docker Compose 中,networks
是用来定义和管理容器间的网络连接的。通过 networks
,你可以控制容器如何与其他容器以及外部环境(如宿主机或外部网络)进行通信。容器在同一个网络中可以通过容器名称直接进行通信。通过创建不同的网络,你可以 隔离容器,限制哪些容器可以相互通信。
默认网络
如果你不在 docker-compose.yml
中显式定义网络,Docker Compose 会自动为你创建一个名为项目名称的默认网络,容器之间可以通过容器名称相互通信。
自定义网络
services:app:image: node-appnetworks:- mynetwork # 将 app 服务连接到 mynetwork 网络db:image: mysqlenvironment:MYSQL_ROOT_PASSWORD: examplenetworks:- mynetwork # 将 db 服务连接到 mynetwork 网络networks:mynetwork:driver: bridge # 使用默认的 bridge 网络驱动
网络驱动类型
Docker 提供了多种网络驱动类型,你可以选择适合你需求的驱动:
-
bridge:默认的网络驱动,适用于单主机的容器通信。
-
host:容器共享宿主机的网络栈,适用于高性能要求。
-
overlay:用于跨主机的容器通信,通常用于 Docker Swarm 集群。
-
none:禁用容器的网络功能。
-
macvlan:容器与宿主机共享 IP 地址,适用于需要容器具备独立 IP 地址的情况。
contain_name
在 Docker Compose 中,container_name
用来 指定容器的名称,这样你可以更方便地引用容器。默认情况下,Docker 会根据服务名和项目名(Docker Compose 文件所在目录的名称)自动生成容器名称,但你可以通过 container_name
字段来手动设置容器名称。
默认容器命名
如果你不指定 container_name
,Docker 会根据以下规则生成容器名称:
<project_name>_<service_name>_<index># <project_name> 是你的 Docker Compose 项目名称,通常是你的文件夹名称(即 docker-compose.yml 文件所在的目录名)。# <service_name> 是服务在 docker-compose.yml 中定义的名称。# <index> 是容器的索引,如果有多个容器(如服务有多个副本),会加上索引编号。
手动命名
services:web:image: nginxcontainer_name: my_custom_web # 指定容器名称为 my_custom_webports:- "8080:80"
environment
在 Docker 中,environment
是一个非常重要的配置项,它用于设置容器的环境变量。环境变量可以帮助你在容器运行时传递配置和敏感信息,例如数据库连接信息、API 密钥、运行时配置等。
services:app:image: my-backend-appenvironment:- DB_HOST=localhost- DB_PORT=3306- DB_USER=root- DB_PASSWORD=mysecretpassword
environment
的几种使用方式
(1) 列表格式
services:app:image: my-backend-appenvironment:- DB_HOST=localhost- DB_PORT=3306
(2) 字典格式
services:app:image: my-backend-appenvironment:DB_HOST: localhostDB_PORT: 3306
(3)引用外部环境变量
你可以使用 ${}
语法从宿主机或 .env
文件中引用外部环境变量。在这种情况下,Docker Compose 会读取宿主机的环境变量或 .env
文件中的变量,并将其传递给容器。
version: '3.8'services:app:image: my-backend-appenvironment:- DB_PASSWORD=${DB_PASSWORD}
(4)使用默认值
version: '3.8'services:app:image: my-backend-appenvironment:- DB_HOST=${DB_HOST:-localhost}- DB_PORT=${DB_PORT:-3306}
command
在 Docker Compose 里,command
的作用就是覆盖镜像默认启动命令。每个镜像在构建时都会在 Dockerfile 里定义一个默认的 CMD
或 ENTRYPOINT
,容器启动时会执行它。如果在 docker-compose.yml
中写了 command
,那么会替换掉镜像里的默认命令。
不写 command
:
version: '3'
services:redis:image: redis:5.0.4container_name: my-redisports:- "6379:6379"# 容器启动时会执行 镜像默认命令:redis-server
写了 command
:
version: '3'
services:redis:image: redis:5.0.4container_name: my-redisports:- "6379:6379"command: redis-server --appendonly yes --requirepass "123456"#容器启动时执行的命令变成:redis-server --appendonly yes --requirepass "123456"
env_file
在 docker-compose 里,env_file
是用来指定一个或多个 环境变量文件 的配置项。和 environment
字段一样,都是给容器注入环境变量,不过 env_file
更适合把一堆环境变量集中写在单独的文件里,方便管理和复用。
version: '3'
services:app:image: myapp:latestenv_file:- .env- ./config/app.env
env 文件格式
env_file
指定的文件,语法基本和 .env
一致,每一行一个变量:
# app.env
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=123456
depends_on
depends_on
用来定义 服务之间的启动依赖关系,只控制容器的启动顺序,不保证依赖服务里的应用已经准备就绪。
version: '3'
services:app:build: .depends_on:- db- redisdb:image: mysql:5.7redis:image: redis:6
#当你执行 docker-compose up app 时,db 和 redis 会被先启动,然后再启动 app。
healthcheck
在 docker-compose 里,healthcheck
用来定义 容器健康检查 的规则,用于判断容器里的服务是否真正可用,而不仅仅是容器进程是否在跑。
version: '3.9'
services:db:image: mysql:5.7healthcheck:test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]interval: 10s # 检查间隔timeout: 5s # 单次检查超时时间retries: 3 # 连续失败次数,超过就标记为 unhealthystart_period: 30s # (可选) 容器启动后的宽限期
配合 depends_on
version: '2.4'
services:app:image: myapp:latestdepends_on:db:condition: service_healthydb:image: mysql:5.7healthcheck:test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]interval: 10stimeout: 5sretries: 5
#这样 app 会等到 db 通过健康检查之后才启动(只在 v2.4 里支持条件,v3 里 depends_on 不支持 condition)。
sysctls
sysctls
用来设置容器的 内核参数(Linux 内核的 sysctl 参数)。它相当于在宿主机里用 sysctl -w key=value
,但作用范围只在该容器中生效,不会影响整个宿主机。
version: '3.9'
services:app:image: nginx:alpinesysctls:net.core.somaxconn: 1024net.ipv4.tcp_syncookies: 0
ulimits
ulimits
用来配置容器内进程的 资源限制,相当于 Linux 里的 ulimit
命令(用户级进程限制)。
version: '3.9'
services:app:image: myapp:latestulimits:nproc: 65535 # 最大进程数nofile:soft: 1024 # 打开的文件数(软限制)hard: 2048 # 打开的文件数(硬限制)
build
build
用来定义 如何构建镜像。当你不是直接用 image:
拉现成镜像,而是需要自己写 Dockerfile
打包时,就会用到 build
。
services:web:build:context: ./dir # 构建上下文(Dockerfile 所在目录)dockerfile: Dockerfile.dev # 指定 Dockerfile 文件名(默认是 Dockerfile)args: # 传递构建参数 (对应 Dockerfile 里的 ARG)APP_ENV: productionAPP_VERSION: "1.0.0"target: builder # 指定构建阶段 (multi-stage build 时用)cache_from: # 使用已有镜像作为构建缓存- myapp:cache
ARGS
ARG
是 Docker 构建镜像时的 构建参数。ARG
只能在 docker build
阶段 使用,不会保留在最终镜像里。
在 Dockerfile 中使用
# 定义构建参数
ARG APP_VERSION=1.0.0# 使用构建参数
FROM openjdk:17
ARG APP_VERSION
LABEL version=$APP_VERSION
在 docker-compose 中传递 args
version: '3.9'
services:app:build:context: .dockerfile: Dockerfileargs:APP_VERSION: "2.0.0"NODE_ENV: productionimage: myapp:2.0
ARG
vs ENV
对比点 | ARG | ENV |
---|---|---|
定义位置 | Dockerfile 里(ARG ) | Dockerfile 里(ENV )或 compose 里 |
生效范围 | 只在 build 阶段 | build 阶段 + 容器运行阶段 |
默认值 | 可以定义 | 可以定义 |
是否写进镜像 | 不会保留 | 会保留 |
是否能在运行时覆盖 | 不能 | 可以用 docker run -e 覆盖 |
Docker Compose 常用命令
基本命令
命令 | 作用 | 示例 |
---|---|---|
docker compose up | 启动服务,如果容器不存在则创建 | docker compose up |
docker compose up -d | 后台启动服务(Detached 模式) | docker compose up -d |
docker compose down | 停止并删除容器、网络、卷 | docker compose down |
docker compose stop | 停止服务,但不删除容器 | docker compose stop |
docker compose start | 启动已存在的容器 | docker compose start |
docker compose restart | 重启服务 | docker compose restart |
查看信息
命令 | 作用 | 示例 |
---|---|---|
docker compose ps | 查看 Compose 项目下的容器状态 | docker compose ps |
docker compose logs | 查看服务日志 | docker compose logs |
docker compose logs -f | 实时跟踪日志 | docker compose logs -f web |
docker compose top | 查看容器内部进程 | docker compose top |
构建与更新镜像
命令 | 作用 | 示例 |
---|---|---|
docker compose build | 根据 Dockerfile 构建镜像 | docker compose build web |
docker compose pull | 从远程仓库拉取镜像 | docker compose pull redis |
docker compose push | 将本地镜像推送到远程仓库 | docker compose push myapp |
执行容器内命令
命令 | 作用 | 示例 |
---|---|---|
docker compose exec <service> <cmd> | 在运行中的容器里执行命令 | docker compose exec web bash |
docker compose run <service> <cmd> | 以新容器运行一次命令(不会启动所有依赖服务) | docker compose run redis redis-cli |
Docker Compose 快速入门与实践
一、环境准备
在开始之前,你需要准备一台可以联网的 Linux 服务器(云服务器、虚拟机都可以),并且能够通过 SSH 工具(推荐使用 FinalShell 或 Xshell)连接到它。
1.在 VMware 中创建虚拟机,完成后启动虚拟机,按照系统安装流程,设置 root
用户密码。
2. 查看虚拟机 IP 地址
3.使用 FinalShell 连接虚拟机
4.连接成功后,你应该能看到类似这样的命令行界面:
二、安装 Docker 与 Docker Compose
在 Linux 环境中,Docker 和 Docker Compose 是必须的工具。我们先来安装它们。
卸载旧版本(如果之前安装过的话)
yum remove docker docker-common docker-selinux docker-engine
安装需要的软件包, yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
设置 yum 源
yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo(中央仓库)yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo(阿里仓库)
查看可用版本有哪些
yum list docker-ce --showduplicates | sort -r
安装最新稳定版 Docker+compose
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完毕查看version
docker --version
docker compose version
启动docker
systemctl start dockersudo systemctl start dockersudo systemctl enable docker
三、创建示例项目并上传
1.创建一个docker-compose.yml文件并设置服务信息
version: '3'
services:redis:image: redis:latest container_name: redisports:- "6379:6379"volumes: - "./data/redis:/data"environment:- TZ=Asia/Shanghairabbitmq:image: rabbitmq:managementcontainer_name: rabbitmqports:- "5672:5672" # RabbitMQ 默认通信端口- "15672:15672" # RabbitMQ Web 管理界面端口environment:- RABBITMQ_DEFAULT_USER=guest # 默认用户名- RABBITMQ_DEFAULT_PASS=guest # 默认密码volumes:- "./data/rabbitmq:/var/lib/rabbitmq" # 持久化 RabbitMQ 数据networks:- mynetworknetworks:mynetwork:driver: bridge
2.在虚拟机中创建工作目录,上传 docker-compose.yml
文件
拉取镜像:Docker Compose 会自动帮你拉取,如果镜像不存在的话。也可以手动的拉取镜像
docker pull redis
docker pull rabbitmq
问题
在linux终端中通过 docker pull 命令拉取镜像,报错无法拉取镜像,这是因为 Docker 客户端无法连接到 Docker 镜像仓库(Docker Hub)
解决
配置国内可用的 Docker镜像加速器,这些镜像加速器用于提高从Docker Hub等公共仓库拉取镜像的速度,如下,配置了4个docker镜像加速器:
vim /etc/docker/daemon.json{
"registry-mirrors": ["https://docker.m.daocloud.io","https://dockerproxy.com","https://docker.mirrors.ustc.edu.cn","https://docker.nju.edu.cn"]
}
重启docker服务,使修改的配置生效:
systemctl daemon-reload
systemctl restart docker
3.切换到该目录,启动docker-compose
cd /home/wq/composeTest
docker compose up -d
四、测试
测试 Redis
用 redis-cli,在宿主机或容器中执行:
# 进入 Redis 容器:docker exec -it redis redis-cli#然后输入:ping#正常返回:PONG#如果你设置了密码,需要先登录:auth yourpasswordping
测试 RabbitMQ
#在浏览器访问:http://<虚拟机IP>:15672#默认账号:#用户名:guest#密码:guest#可以看到 虚拟主机、队列、连接 等信息,说明服务正常。
五、idea测试运行
1.Maven中需要有 Redis 和 RabbitMQ 的依赖,例如:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
2.配置 application.yml
spring:redis:host: 192.168.101.128 # 如果是在虚拟机上运行,替换为虚拟机的 IP 地址port: 6379jedis:pool:max-idle: 10min-idle: 1max-wait: 10000msrabbitmq:host: 192.168.101.128port: 5672stream:username: guestpassword: guestvirtual-host: /
server:port: 1010
3.测试代码
Redis 测试代码
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, String> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new StringRedisSerializer());return template;}
}/*** Redis控制器类,提供基于HTTP的Redis操作接口* 使用@RestController注解标记为RESTful控制器,所有方法默认返回JSON格式数据*/
@RestController
public class RedisController {/*** 自动注入RedisTemplate实例* 用于执行Redis操作,泛型指定键和值均为String类型*/@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 设置键值对的接口* @param key 要设置的键* @param value 要设置的值* @return 返回设置成功的提示信息*/@GetMapping("/set")public String setValue(@RequestParam("key") String key, @RequestParam("value") String value) {redisTemplate.opsForValue().set(key, value);return "Value set successfully";}/*** 获取键对应值的接口* @param key 要获取的键* @return 返回获取到的值,格式为"Value:实际值"*/@GetMapping("/get")public String getValue(@RequestParam("key") String key) {return "Value:"+redisTemplate.opsForValue().get(key);}
}
#访问 http://localhost:1010/set?key=testKey&value=HelloRedis
#显示 Value set successfully则成功
rabbitMq测试代码
@EnableRabbit
@SpringBootApplication
public class ComposeTestApplication {public static void main(String[] args) {SpringApplication.run(ComposeTestApplication.class, args);}}
/*** RabbitMQ配置类* 用于配置RabbitMQ的队列、交换机和绑定关系*/
@Configuration
public class RabbitMQConfig {/*** 定义队列* @return Queue对象,队列名为"queue",非持久化*/@Beanpublic Queue queue() {return new Queue("queue", false);}/*** 定义主题交换机* @return TopicExchange对象,交换机名为"exchange"*/@Beanpublic TopicExchange exchange() {return new TopicExchange("exchange");}/*** 定义队列与交换机的绑定关系* @param queue 队列对象* @param exchange 交换机对象* @return Binding对象,使用routingKey将队列绑定到交换机*/@Beanpublic Binding binding(Queue queue, TopicExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("routingKey");}
}
/*** RabbitMQ控制器类,用于处理消息发送相关的HTTP请求* 使用@RestController注解标记这是一个RESTful控制器,所有方法都会返回JSON格式的响应*/
@RestController
public class RabbitMQController {/*** 自动注入AmqpTemplate实例,用于与RabbitMQ进行交互* AmqpTemplate是Spring AMQP提供的核心接口,用于发送和接收消息*/@Autowiredprivate AmqpTemplate amqpTemplate;/*** 处理GET请求的消息发送端点* 当访问/send端点并带有message参数时,此方法会被调用** @param message 要发送的消息内容,通过HTTP请求参数传递* @return 返回确认消息发送成功的响应字符串*/@GetMapping("/send")public String sendMessage(@RequestParam("message") String message) {// 使用AmqpTemplate将消息发送到指定的交换机和路由键// 参数1: "exchange" - 目标交换机的名称// 参数2: "routing.key" - 消息的路由键// 参数3: message - 要发送的消息内容amqpTemplate.convertAndSend("exchange", "routingKey", message);// 返回消息发送成功的确认信息return "Message sent: " + message;}
}
@Component
public class RabbitMQListener {/*** 监听指定队列的消息处理方法* @param message 接收到的消息内容,类型为String* 当队列"queue"中有消息时,此方法会被自动调用*/@RabbitListener(queues = "queue")public void listen(String message){System.out.println("Message received: " + message);}}
#浏览器访问 http://localhost:1010/send?message=HelloRabbitMQ
#页面输出:Message sent: HelloRabbitMQ
#控制台输出:Message received: HelloRabbitMQ
六、Jar 包测试
1.在 IDEA 中通过 Maven 打包 Jar
2.打包完成后,可以在项目根目录下的target目录中找到生成的 Jar,上传到虚拟机
3.在虚拟机运行 Jar
java -jar ComposeTest-0.0.1-SNAPSHOT.jar --server.port=1010 --server.address=0.0.0.0
4.测试
测试 Redis
http://192.168.101.128:1010/set?key=testKey&value=HelloRedis
测试rabbitMq
http://192.168.101.128:1010/send?message=HelloRabbitMQ
http://192.168.101.128:15672