插件dockerfile-maven-plugin,Docker部署SpringBoot多模块、多环境项目、Redis、Mysql、RocketMQ,推送阿里云镜像仓库服务,去疑真香版
本文主要讲解多模块的springboot如何通过maven的插件dockerfile-maven-plugin如何配置,如何打包上传服务器,如何推送到阿里云镜像仓库服务,多环境下如何配置、如何打包上传,如何用docker安装Redis,Mysql,RocketMQ镜像和容器。
目录
5.子工程portal依赖的common模块pom.xml配置
9. 在Maven配置文件settings.xml中添加com.spotify
7.1 RemotingTooMuchRequestException: sendDefaultImpl call timeout
7.2 MQBrokerException:CODE: 17 DESC: topic
本文主要讲解多模块的springboot如何通过maven的插件dockerfile-maven-plugin如何配置,如何打包上传服务器,如何推送到阿里云镜像仓库服务,多环境下如何配置、如何打包上传,如何用docker安装Redis,Mysql,RocketMQ镜像和容器
一、阿里云服务器
我是第一次用阿里云,可以免费使用几个月的阿里云服务器,选择了2核(vCPU),内存2 GiB,同时选择了预装的Docker,就不单独下载安装docker了
具体配置阿里云服务器可参考部署springboot项目到阿里云服务器(小白包会)_阿里云部署springboot项目-CSDN博客
二、多模块、多环境配置
手工将springboot项目的jar包上传到服务器,在build镜像,其实挺麻烦的,而通过docker-maven-plugin插件,就很方便,但是这个已经过时,官方推荐使用插件dockerfile-maven-plugin。
docker-maven-plugin不需要先写Dockerfile,打包成功后会自动生成Dockerfile,而dockerfile-maven-plugin依赖于一部分Dockerfile,配置相对docker-maven-plugin少了很多,但是对于初学者理解起来就难了些。
说到多模块、多环境,maven在使用插件dockerfile-maven-plugin时。涉及到父工程、子工程,子工程依赖的模块,不同的环境,不同的资源,如何配置,配置放在哪里,启动工程和依赖模块如何协调配置等等,才能正确打包。
下面以我的项目讲解,多模块项目如下
1.多模块项目
SBSec2Demo是父工程,portal是要启动的子工程模块,依赖common模块
2. 父工程pom主要配置
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SBSec2Demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>common</module>
<module>auth</module>
<module>portal</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.12</version>
<relativePath/>
</parent>
<properties>
<docker.maven.plugin.version>1.4.13</docker.maven.plugin.version>
<!--默认全局跳过,然后需要dockerfile打包镜像的模块加上相反配置,覆盖全局默认跳过即可-->
<dockerfile.skip>true</dockerfile.skip>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${docker.maven.plugin.version}</version>
<executions>
<execution>
<id>tag-latest</id>
<phase>deploy</phase>
<goals>
<!--如果package时不想用docker打包,就注释掉这个goal-->
<goal>build</goal>
<goal>tag</goal>
<!-- <goal>push</goal>-->
</goals>
<configuration>
<tag>latest</tag>
</configuration>
</execution>
</executions>
<configuration>
<!-- 上下文路径配置,此处设置为项目根路径 用来读取Dockerfile-->
<contextDirectory>${project.basedir}</contextDirectory>
<repository>${project.artifactId}</repository>
<tag>latest</tag>
<!-- 作为Dockerfile文件传入-->
<buildArgs>
<!--<WAR_FILE>${war.explode.directory}</WAR_FILE>-->
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
3.父工程pom插件配置疑问
如果是没操作过该插件推送镜像到服务器,对 <contextDirectory>配置会有疑问,这里取得不是父工程的Dockerfile吗,难道Dockerfile要放到父工程SBSec2Demo下,那我不同子工程的dockerfile肯定是不一样的,怎么处理呢,看我上面工程截图就知道,SBSec2Demo下是没有Dockerfile文件的,在父工程路径下执行打包命令时,就是取得子工程的Dockerfile,但需要父工程pom.xml配置<properties><dockerfile.skip>true</dockerfile.skip> </properties>
Dockerfile放在要启动的子工程即可,我的是放在子工程portal下面,如下图
如果鼠标放在<repository>${project.artifactId}</repository>中的project.artifactId提示的是当前父工程SBSec2Demo,对于初学者来说,很疑惑,和上面讲的一样疑惑问题,这个artifactId肯定不是我想要的上传到服务器的镜像名称,是不是要配置到子工程中去,岂不是整个插件配置<configuration>都要移动到子工程,然而我也一开始有这样的疑问,实际是,在父工程路径下执行打包命令时,最后取的artifactId就是子工程的artifactId,比如我的就是portal,而不是SBSec2Demo。当然上述都需要按子工程portal下的pom.xml如下配置。
启动子工程portal下的pom.xml配置如下,其中 <dockerfile.skip>false</dockerfile.skip>意思是父工程路径下执行打包命令时,该子工程要打包,不跳过,像依赖的common模块就不会生成镜像,也不会因为父工程和common其他模块因为没有Dockerfile文件而打包失败,报找不到Dockerfile文件的失败,也就是子工程这样打包即可
4. 子工程portal模块pom配置
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SBSec2Demo</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>portal</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>portal</name>
<description>portal project for sec</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<dockerfile.skip>false</dockerfile.skip>
</properties>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<!--不加版本无法引用-->
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--在子工程 , 执行 mvn dockerfile:push 命令,即推送镜像到阿里云镜仓库服务-->
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${docker.maven.plugin.version}</version>
<configuration>
<tag>${project.version}</tag>
</configuration>
</plugin>
</plugins>
</build>
</project>
5.子工程portal依赖的common模块pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SBSec2Demo</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
</project>
6.配置环境变量DOCKER_HOST
同时,使用插件dockerfile-maven-plugin还要本地电脑配置环境变量DOCKER_HOST,写到这里有个疑惑,我还没去验证解决,难道推到不同的机器,DOCKER_HOST环境变量都要改一下吗,是否可配置多个机器呢,如果不能,就只能用推到阿里云镜像仓库服务了,当然也可以推到其他镜像服务,也可以推到自己的私服,比如电脑配置的服务器就可以当成镜像的私服,这里就不展开了
7.修改宿主机的docker配置,让其可以远程访问
vi /lib/systemd/system/docker.service
# 在ExecStart=后添加配置
‐H tcp://0.0.0.0:2375 ‐H unix:///var/run/docker.sock
刷新配置重启服务
# 通知docker服务做出的修改
systemctl daemon-reload
# 重启docker服务
systemctl stop docker
systemctl restart docker
8.开启2375端口
1 先通过systemctl status firewalld命令查看一下防火墙的状态,发现当前是dead状态,即防火墙未开启。
systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
2 通过systemctl start firewalld命令开启防火墙
3 修改防火墙策略,允许访问2375端口:
#开放2375/tcp端口
firewall-cmd --zone=public --add-port=2375/tcp --permanent
#更新防火墙的设置,使上面的修改生效
firewall-cmd --reload
查看防火墙开放状态:
#查看所有打开的端口
firewall-cmd --zone=public --list-ports
9. 在Maven配置文件settings.xml中添加com.spotify
<pluginGroups>
<pluginGroup>com.spotify</pluginGroup>
</pluginGroups>
10.阿里云开放 2375端口
需要到阿里云/云服务器 ECS/安全组/管理规则添加端口 2375/2375,以及其他要访问的端口
11.父工程SBSec2Demo执行打包
D:\IDEAWorkSpace\SBSec2Demo> mvn clean package
执行完上述命令就会把镜像推送到配置的服务器,因为还未配置阿里云镜像仓库服务,不会推到阿里云,即使配置了,也不会推送到阿里云,这步操作仅仅会把镜像推送到服务器,推送的镜像如下
因为我的项目还依赖Redis,Mysql,RocketMq, 所以这里不启动jar包,不执行运行后端jar包命令
sudo docker run -d -p 8082:8082 --name portal 10f984363ffd
三 多环境下如何打包
1.多模块、多环境工程框架
上面是演示了如何多模块打包,在上述基础上,子工程portal多环境配置如下
2.多模块、多环境工程配置
常见的springboot多模块、多环境 application的yml配置如上,在哪个路径下执行打包命令,Dockerfile如何配置,打包命令是什么样的,才能打成想要的环境配置,这里不讲不同环境的application的yml如何配置,首先通用配置如下,
只需子工程portal下的pom.xml新增配置 <profiles></profiles>、<build> <resources> </resources></build>,在上面的pom基础上修改配置如下
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SBSec2Demo</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>portal</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>portal</name>
<description>portal project for sec</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<dockerfile.skip>false</dockerfile.skip>
</properties>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<!--不加版本无法引用-->
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<profiles>
<!-- 本地环境 -->
<profile>
<id>local</id>
<properties>
<spring.profiles.active>local</spring.profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 开发环境 -->
<profile>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<!-- 生产环境 -->
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--在子工程 , 执行mvn dockerfile:push 命令,即推送阿里云镜像-->
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${docker.maven.plugin.version}</version>
<configuration>
<tag>${project.version}</tag>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- true表示利用占位符进行替换 -->
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>application.yml</include>
<!-- ${spring.profiles.active}就是我们指定的环境,会被替换掉 -->
<include>application-${spring.profiles.active}.yml</include>
<include>**/*.xml</include>
<include>**/*.html</include>
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.png</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
</build>
</project>
3.多模块、多环境工程打包命令
比如想打成dev环境的包,在父工程目录下执行如下打包命令即可,
D:\IDEAWorkSpace\SBSec2Demo> mvn clean package -P dev
执行完毕,portal镜像就推送到了服务器
查看jar包,只打入了application-dev.yml,是想要的jar包,其他资源文件像mapper.xml也打入进去了。
四、Docker 安装中间件
1.docker常用命令
讲docker安装Nginx,Redis,Mysql,RocketMQ之前,先说一些命令
1.安装后查看Docker版本
docker -v
2.操作镜像
systemctl命令是系统服务管理器指令,它是 service 和 chkconfig 两个命令组合。
启动docker:systemctl start docker
停止docker:systemctl stop docker
重启docker:systemctl restart docker
查看docker状态:systemctl status docker
开机启动:systemctl enable docker
查看docker概要信息:docker info
查看docker帮助文档:docker --help
docker rmi $IMAGE_ID:删除指定镜像
docker rmi `docker images -q`:删除所有镜像
3.查看容器
查看正在运行容器:docker ps
查看所有的容器(启动过的历史容器):docker ps -a
查看最后一次运行的容器:docker ps –l
查看停止的容器docker ps -f status=exited
4 操作容器
docker logs -f 容器id
# -f: 可以滚动查看日志的最后几行
删除镜像
docker rmi 镜像的标识
标识可以是id或者name。
删除容器(删除容器前,需要先停止容器)
docker stop 容器id
# 删除指定容器
docker rm 容器id
启动容器
docker start 容器id
5 登录进入容器
docker exec -it container_name (或者 container_id) /bin/bash(exit退出时,容器不会停止)
6.文件拷贝\挂载
在容器内编辑配置文件不方便,我们可以先将配置文件从容器内拷贝到宿主机,编辑修改后再拷贝回去。
6.1 将文件从容器内拷贝出来
docker cp 容器名称:容器目录 需要拷贝的文件或目录
例如修改nginx.conf::docker cp nginx:/etc/nginx/nginx.conf /data/nginx/conf/nginx.conf
6.2 将文件拷贝到容器内可以使用cp命令
docker cp 需要拷贝的文件或目录 容器名称:容器目录
例如修改后nginx.conf:docker cp /data/nginx/conf/nginx.conf nginx:/etc/nginx/nginx.conf
拷贝到容器后,重新启动容器
7 目录挂载
这样复制来复制去很麻烦
我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器。
创建容器 添加-v参数 后边为 宿主机目录:容器目录
docker run --name nginx -d -p 80:80 -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /data/nginx/logs:/var/log/nginx -v /root/test/dist:/usr/share/nginx/html nginx
开发调试中肯定想知道安装的容器内存占用和CPU使用情况,下面的命令就可以满足
# 实时显示容器的CPU和内存使用情况
docker stats
docker stats 容器id
# 查看容器的配置信息和状态,包括内存限制。
docker inspect 容器id
使用--format选项来仅显示内存使用情况:
docker inspect --format='{{.HostConfig.MemoryUsage}}' <container_id_or_name>
# 显示Docker对象(包括容器、镜像、本地卷)的磁盘使用情况。
docker system df
# 查看容器的内存使用情况
cat /sys/fs/cgroup/memory/docker/<container_id>/memory.usage_in_bytes
2. 配置阿里云镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ahu17w8b.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.安装JDK
1.先搜索jdk:docker search jdk8
docker pull 搜索到的jdk镜像名称(例如kdvolder/jdk8)
docker pull kdvolder/jdk8
用docker启动 docker run -di --name=jdk1.8 kdvolder/jdk8
查看下载的jdk版本
docker exec -it jdk1.8 /bin/bash
java -version
4.下载mysql镜像
按2.2启动后过了一会儿可能会报mysql in docker mbind Operation not permitted,启动的容器挂掉了,如果报可以参考2.3启动
2.1 docker pull mysql
2.2 docker run -di --name=sbsec_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=wcf123456 mysql
2.2.1 这一步运行报错,重启docker就行,如果存在旧的sbsec_mysql容器删除
systemctl restart docker
2.3 docker ps 查看创建的容器
docker logs -f 92785f57ac18
过了一会儿如果报 mysql报mysql in docker mbind Operation not permitted
如果知道怎么配置my.cnf可以按下述启动
mkdir -p /data/mysql/conf /data/mysql/data
touch my.cnf
docker run -d --name sbsec_mysql -m 1g -p 3306:3306 -v /data/mysql/conf/my.cnf:/etc/my.cnf -v /data/mysql/data:/var/lib/mysql --privileged=true --restart=always --security-opt seccomp=unconfined -e MYSQL_ROOT_PASSWORD=wcf123456 -e TZ=Asia/Shanghai mysql
不清楚按下述启动
docker run -d --name sbsec_mysql -m 1g -p 3306:3306 --privileged=true --restart=always --security-opt seccomp=unconfined -e MYSQL_ROOT_PASSWORD=wcf123456 -e TZ=Asia/Shanghai mysql
2.4 docker exec -it sbsec_mysql /bin/bash 进入容器
2.5 登录Mysql
mysql -u root -p 从容器进入mysql,回车让输入mysql密码即可进入
Enter password:
2.6.创建数据源,分号为结束语句
create database sbdemodb;
2.7 进入数据源
use test;
2.8 创建表
create table test1(id int,name varchar(20));
2.9 插入数据
insert into test1 values(1,'yan')
3.0 查询数据
select * from test1;
3.1 修改密码
ALTER USER 'root'@'%' IDENTIFIED BY '<new password>' PASSWORD EXPIRE NEVER;
ALTER USER 'root'@'localhost' IDENTIFIED BY '<new password>';
3.退出,重启 docker挂载的mysql
exit;
2.6 quit 退出容器中的mysql,回到mysql容器
2.7 exit 退出容器
登录成功,就可以到Navicat连接操作了
查看mysql镜像信息、版本了什么的
docker inspect 镜像ID
5.拉取Nginx镜像
1. docker pull nginx
2.创建Nginx容器
docker run -di --name=nginx -p 80:80 nginx/bin/b
配置反向代理
官方的nginx镜像,nginx配置文件nginx.conf 在/etc/nginx/目录下。
在容器内编辑配置文件不方便,我们可以先将配置文件从容器内拷贝到宿主机,编辑修改后再拷贝回去。
(1)从容器拷贝配置文件到宿主机
docker cp nginx:/etc/nginx/nginx.conf /data/nginx/conf/nginx.conf
(2)编辑nginx.conf,添加反向代理配置
upstream tomcat-cas {
server IP地址:8082;
}
server {
listen 80;
server_name demo.sbsec.com;
location / {
proxy_pass http://tomcat-cas;
index index.html index.htm;
}
}
(3)将修改后的配置文件拷贝到容器
docker cp /data/nginx/conf/nginx.conf nginx:/etc/nginx/nginx.conf
3 上述也可以启动Nginx直接挂载
docker run --name nginx -d -p 80:80 -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /data/nginx/logs:/var/log/nginx -v /root/test/dist:/usr/share/nginx/html nginx
(4)重新启动容器
docker restart nginx
(5)设置域名指向
IP地址 demo.sbsec.com
6.拉取Redis镜像
docker pull redis
创建Redis容器 参考 https://blog.csdn.net/javaxueba/article/details/134800960?fromshare=blogdetail&sharetype=blogdetail&sharerId=134800960&sharerefer=PC&sharesource=qq_35683545&sharefrom=from_link
1-新建文件夹
[root@syf/]# mkdir -p /data/dockerData/redis/conf
[root@syf/]# cd /data/dockerData/redis/conf
2-创建文件
[root@syf conf]# touch redis.config
[root@syf conf]# ls
redis.config
3-编写文件内容 (进入后 i 子母键插入,黏贴下面配置,:wq! 保存并退出)
[root@syf conf]# vim redis.config
4 docker run -p 6379:6379 --name sbsec_redis -v /data/dockerData/redis/conf/redis.config:/etc/redis/redis.conf -v /data/dockerData/redis/data:/data -v /data/dockerData/redis/logs:/logs -d redis redis-server /etc/redis/redis.conf
5.1-进入redis容器
[root@iZuf6hxabqikytnrumsi4gZ logs]# docker exec -it a34aff536643 bash
2-连接redis
root@a34aff536643:/data# redis-cli
3-输入密码
127.0.0.1:6379>auth wcf123456
OK
6 最后一定要开放防火墙
输入指令:firewall-cmd --zone=public --add-port=6379/tcp --permanent,开放防火墙指定端口。
输入指令:firewall-cmd --reload,重新加载防火墙。
redis拉取截图,redis.confg具体配置可参考
docker 安装Redis (全网最详细:附带配置文件)-CSDN博客
redis在阿里云服务器开启防火墙,ip设置为百度出来的本机ip地址,设置的太宽泛,极易遭到病毒攻击,密码也要设置复杂些
7.拉取RocktMQ镜像
7.1 docker pull rocketmqinc/rocketmq
7.2 创建nameserver数据存储目录
rocketMQ 分为nameserver和broker两部分,在启动时应该先启动nameserver,因此我们现在先创建nameserver的日志和数据存放目录。
mkdir -p /mydata/namesrv/logs /mydata/namesrv/store
logs:是nameserver的日志目录,store:是nameserver的数据目录
7.3 第三步:构建namesrv容器并启动
docker run -d --restart=always --name rmqnamesrv -p 9876:9876 \
-v /mydata/namesrv/logs:/root/logs \
-v /mydata/namesrv/store:/root/store \
-e "MAX_POSSIBLE_HEAP=100000000" rocketmqinc/rocketmq sh mqnamesrv
7.4 创建broker数据存储路径 操作这步之前,我们已经将nameserver启动成功
mkdir -p /mydata/broker/logs /mydata/broker/store /data/broker/conf
logs:是broker的日志目录,store:是broker的数据目录,conf是broker的配置信息目录
7.5 创建broker配置文件
cd /data/broker/conf
touch broker.conf
vim broker.conf
7.6 请将一下信息复制到broker.conf文件中,请注意修改brokerIP1,改为您服务器的IP地址!!!!请注意修改namesrvAddr,改为您nameserver的IP地址!!
!!
7.7 构建broker容器并启动
docker run -d --restart=always --name rmqbroker01 --link rmqnamesrv:namesrv -p 10911:10911 -p 10909:10909 -v /mydata/broker/logs:/root/logs -v /mydata/broker/store:/root/store -v /data/broker/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf -e "NAMESRV_ADDR=namesrv:9876" -e "MAX_POSSIBLE_HEAP=200000000" rocketmqinc/rocketmq sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf
7.8 rocketmq-console可视化界面 拉取rocketmq-console镜像
docker pull pangliang/rocketmq-console-ng
7.9 构建rocketmq-console容器并启动
docker run -d --restart=always --name rocketmq-console-ng \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=IP地址:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 9999:8080 pangliang/rocketmq-console-ng
7.0 登录管理台
http://IP地址:9999/
如果登录不上,需要到阿里云/云服务器 ECS/安全组/管理规则添加端口 9999/9999,8080/8080
添加后就能登录成功
进入管理台界面后,如果报连接异常,
需要到阿里云/云服务器 ECS/安全组/管理规则添加端口 9876/9876
broker.conf配置可参考
docker 安装roketmq_docker安装rockckmq-CSDN博客
7.1 RemotingTooMuchRequestException: sendDefaultImpl call timeout
在实际使用中,接口调用时报下面异常,
[2025-01-03 02:59:08:172] [http-nio-8082-exec-2] [ERROR] [org.apache.rocketmq.spring.core.RocketMQTemplate] - syncSend failed. destination:RLT_TEST_TOPIC:tag1, message:GenericMessage [payload=byte[464], headers={contentType=application/json, id=3f147cc1-36d0-c3ac-5066-9bbe30c9e053, timestamp=1735873145170}], detail exception info:
org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
是因为RocketMq Broker启动后,启动的broker-a的端口是10911,云服务器防火墙忘了开放这个端口
在云服务器的控制台开放这个端口后正常运行
7.2 MQClientException: No route info of this topic: RLT_TEST_TOPIC
如果想让服务器更加安全,不被病毒攻击,在阿里云服务器安全组针对9876设置的授权对象ip,该ip是name-server所在的机器,即该ip是118.31.33.173(阿里云服务器),否则配置错误会报No route info of this topic: RLT_TEST_TOPIC
120.35.1.23是百度出来的本机ip地址,
7.3 MQBrokerException:CODE: 17 DESC: topic
解决了上述异常,再调接口又报MQBrokerException: CODE: 17 DESC: topic[RLT_TEST_TOPIC] not exist, apply first please!
Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 17 DESC: topic[RLT_TEST_TOPIC] not exist, apply first please!
See http://rocketmq.apache.org/docs/faq/ for further details. BROKER: 118.31.33.173:10911
at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:779)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:619)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:601)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:545)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:907)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:643)
... 144 common frames omitted
[2025-01-03 03:09:40:842] [http-nio-8082-exec-1] [ERROR] [o.a.c.core.ContainerBase.[Tomcat].[localhost].[/sbSecDemo].[dispatcherServlet]] - Servlet.service() for servlet [dispatcherServlet] in context with path [/sbSecDemo] threw exception [Request processing failed; nested exception is org.springframework.messaging.MessagingException: Send [4] times, still failed, cost [61]ms, Topic: RLT_TEST_TOPIC, BrokersSent: [broker-a, broker-a, broker-a, broker-a]
See http://rocketmq.apache.org/docs/faq/ for further details.; nested exception is org.apache.rocketmq.client.exception.MQClientException: Send [4] times, still failed, cost [61]ms, Topic: RLT_TEST_TOPIC, BrokersSent: [broker-a, broker-a, broker-a, broker-a]
See http://rocketmq.apache.org/docs/faq/ for further details.] with root cause
org.apache.rocketmq.client.exception.MQBrokerException: CODE: 17 DESC: topic[RLT_TEST_TOPIC] not exist, apply first please!
See http://rocketmq.apache.org/docs/faq/ for further details. BROKER: 118.31.33.173:10911
at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:779)
我代码中写了topic,以为就是手动创建了Topic,实际是要么在管理台手动添加该topic,要么改 broker.conf如下,我一开始改成了false
# 是否允许 Broker 自动创建 Topic,建议线下开启,线上关闭 !!!这里仔细看是 false,false,false
autoCreateTopicEnable=true
# 是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
修改后,关掉RocketMq Broke容器,然后重启RocketMq Broker容器,不用重启portal容器 ,接口终于调通
五 启动Springboot工程
执行以下命令10f984363ffd是portal镜像id
sudo docker run -d -p 8082:8082 --name portal 10f984363ffd
查看启动日志 docker logs -f 容器ID
至此, 插件dockerfile-maven-plugin,Docker部署SpringBoot多模块、多环境项目、Redis、Mysql、RocketMQ部署成功。
但是,调接口时报 The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.搞了好久,试了网上的各种方案,都不行,偶然间用Navicat查看表,发现连接超时,以为是msql容器挂了呢,查看服务器mysql容器,还正常运行着,连接了好久才显示docker ps执行的结果,此时再次回到Navicat查看表,也正常连接,我就知道了,是Mysql经常连接超时,造成上述异常,此时调接口,不再报上述的异常,后来过了一会儿再调不是portal容器挂,就是msql报上述异常。推断是可能用的免费的阿里云服务器,用的2核CPU、内存2G,然后一台机器装了Redis、Mysql、RocketMq、jdk、Docker,Springboot项目,运行慢,或者内存不足,导致程序运行慢,甚至程序容器挂掉
六、推送镜像到阿里云
前面讲了,电脑端配置DOCKER_HOST,父工程pom.xml仅仅按前面讲的配置,就能推送到服务器,不会推送到阿里云镜像仓库服务器
具体如何操作阿里云镜像仓库可参考下面的链接,这里不讲这些,只讲其他人没讲的,或者虽然写了各种配置或者步骤,或者步骤省略的,但对于新手来说,还是有很多疑惑,这里一一解惑。
阿里云镜像仓库:拉取和推送Docker镜像_阿里云本地镜像仓库不写tag默认拉取最新的镜像吗?-CSDN博客
1.推送阿里云镜像仓库pom.xml配置
推送阿里云只需在父工程SBSec2Demo根目录下的pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SBSec2Demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>common</module>
<module>auth</module>
<module>portal</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.12</version>
<relativePath/>
</parent>
<properties>
<!--阿里云镜像库-->
<docker.repository.url>crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com</docker.repository.url>
<!--上传的Docker镜像前缀,此前缀一定要和Harbor中的项目名称一致,和阿里云仓库的命名空间一致-->
<docker.registry.name>sbsec</docker.registry.name>
<docker.registry.username>aliyun385854784</docker.registry.username>
<docker.registry.password>wfc123456</docker.registry.password>
<docker.maven.plugin.version>1.4.13</docker.maven.plugin.version>
<!--默认全局跳过,然后需要dockerfile打包镜像的模块加上相反配置,覆盖全局默认跳过即可-->
<dockerfile.skip>true</dockerfile.skip>
</properties>
<dependencies>
<!--省略-->
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${docker.maven.plugin.version}</version>
<executions>
<execution>
<id>tag-latest</id>
<phase>deploy</phase>
<goals>
<!--如果package时不想用docker打包,就注释掉这个goal-->
<goal>build</goal>
<goal>tag</goal>
<!-- <goal>push</goal>-->
</goals>
<configuration>
<tag>latest</tag>
</configuration>
</execution>
</executions>
<configuration>
<!-- 上下文路径配置,此处设置为项目根路径 用来读取Dockerfile-->
<contextDirectory>${project.basedir}</contextDirectory>
<!--使用maven setting认证-->
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<!--上传的仓库路径 registry.cn-hangzhou.aliyuncs.com/namespace/repositoryname-->
<!--上传的仓库路径 crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal-->
<repository>${docker.repository.url}/${docker.registry.name}/${project.artifactId}</repository>
<!-- <repository>${project.artifactId}</repository>-->
<!--子用户名@企业别名 或 子用户名@主账号UID-->
<username>${docker.registry.username}</username>
<!--在容器镜像服务控制台"设置Registry登陆密码-->
<password>${docker.registry.password}</password>
<tag>latest</tag>
<!-- 作为Dockerfile文件传入-->
<buildArgs>
<!--<WAR_FILE>${war.explode.directory}</WAR_FILE>-->
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
如果不想推送到阿里云镜像仓库或者私有镜像仓库 ,不必配置下面4个配置
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<repository>${docker.repository.url}/${docker.registry.name}/${project.artifactId}</repository>
<username>${docker.registry.username}</username>
<password>${docker.registry.password}</password>
仅仅想推送到服务器,然后run启动,只需按第一步父工程pom的配置如下
<contextDirectory>${project.basedir}</contextDirectory>
<repository>${project.artifactId}</repository>
2. 推送到阿里云镜像仓库
前面在父工程SBSec2Demo下执行了打包命令,然后在子工程portal路径下执行
D:\IDEAWorkSpace\SBSec2Demo\portal> mvn dockerfile:push
而其他说的下属这些命令,实际是手动在服务器构建了一个镜像,把服务器上的镜像推送到阿里云服务器,而我们是idea本地用的maven插件dockerfile-maven-plugin自动推送镜像到服务器和阿里云服务器。也就是执行了上述mvn dockerfile:push 就会直接把镜像推送到阿里云镜像仓库,不用使用下述步骤和命令,如果不想推到阿里云镜像仓库,就不用执行mvn dockerfile:push
$ docker pull crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal:[镜像版本号]
报invalid reference format
3. 将镜像推送到Registry 这应该是在服务器操作的,有了maven插件就不用了
$ docker login --username=用户名 crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com
$ docker tag [ImageId] crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal:[镜像版本号]
例如
docker pull crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal:1.0-SNAPSHOT
$ docker push crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
如果想单独在服务器执行推送到阿里云镜像仓库,执行上述命令,[ImageId]和[镜像版本号]参数。填写时是不带[]中括号的
服务器也会同步有一个镜像 crpi-6u8x7l6xhv2zf59d.cn-shenzhen.personal.cr.aliyuncs.com/sbsec/portal ,如下图
更多推荐
所有评论(0)