目录

一、阿里云服务器

二、多模块、多环境配置

1.多模块项目

2. 父工程pom主要配置

3.父工程pom插件配置疑问

4. 子工程portal模块pom配置

5.子工程portal依赖的common模块pom.xml配置

6.配置环境变量DOCKER_HOST

7.修改宿主机的docker配置,让其可以远程访问

8.开启2375端口

 9. 在Maven配置文件settings.xml中添加com.spotify

10.阿里云开放 2375端口

11.父工程SBSec2Demo执行打包

三 多环境下如何打包

1.多模块、多环境工程框架

2.多模块、多环境工程配置

 3.多模块、多环境工程打包命令

​四、Docker 安装中间件

1.docker常用命令

 2. 配置阿里云镜像加速器

3.安装JDK

 4.下载mysql镜像

5.拉取Nginx镜像 

 6.拉取Redis镜像

7.拉取RocktMQ镜像

7.1 RemotingTooMuchRequestException: sendDefaultImpl call timeout

7.2 MQBrokerException:CODE: 17  DESC: topic

 五 启动Springboot工程

六、推送镜像到阿里云

1.推送阿里云镜像仓库pom.xml配置

2. 推送到阿里云镜像仓库


本文主要讲解多模块的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 ,如下图

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐