百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

多模块的微服务项目容器化与Git追踪发布记录

bigegpt 2025-07-02 18:25 4 浏览

在使用了微服务后,一个项目往往由多个模块组成,而容器化发布的建议是单个容器尽量只运行单个进程。所以我们会把每个模块单独打包成镜像运行。如果每个模块都单独配置Dockerfile会让我们维护起来很麻烦。这时我们就需要通过maven的
maven-remote-resources-plugin插件来通过一个Dockerfile模版文件为每个项目生成单独的Dockerfile


配置maven-remote-resources-plugin

  1. 创建配置文件模版项目
# platform-config

<groupId>com.tinem</groupId>
<artifactId>platform-config</artifactId>
<version>0.0.1-SNAPSHOT</version>



  1. Dockerfile模版
# 定义变量$signStart ,因为直接写${}会被转义,所以有些情况下我们想在生产的文件中输出${}就需要通过变量转义

#set($signStart="${")
#set($signStartTwo="{")
#set($signEnd="}")

# 采用alibaba的JDK 版本是:17.0.3.0.3
FROM registry.cn-shanghai.aliyuncs.com/fengzhihao/jdk:alibaba.17.0.3.0.3

# 创建工作文件夹
RUN mkdir /app

# project.build.finalName是maven插件的变量,用于获取编译后输出jar的名字
# 将maven编译后的jar添加到容器中
ADD ${project.build.finalName}.jar /app/${project.build.finalName}.jar

# 默认jvm大小512M
ENV JAVA_OPTS=" -server \
 -Xmx512m \
 -Xms512m \
 -Xmn64m "

# 默认东八区
ENV TZ=Asia/Shanghai

# 创建jvm日志目录
RUN mkdir -p /tmp/com.tinem/jvm_error/dumps/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}/
RUN mkdir -p /tmp/com.tinem/jvm_error/log/${project.build.finalName}

# 切换工作文件夹
WORKDIR /app

# 容器运行时的命令
# mkdir -p /tmp/com.tinem/jvm_error/dumps/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}/
# mkdir -p /tmp/com.tinem/jvm_error/log/${project.build.finalName}
# 这两句是因为生产环境下会将/tmp目录挂载到单独的磁盘。导致容器创建的目录不存在,所以在容器启动时在创建一次
# -XX:+HeapDumpOnOutOfMemoryError 是 Java 虚拟机(JVM)的一个参数,用于在发生内存溢出错误时自动生成堆转储文件。
# -XX:HeapDumpPath  JVM 在发生内存溢出错误时将堆转储文件保存在 /tmp/com.tinem/jvm_error/dumps/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}/ 路径下
# -XX:ErrorFile JVM 在发生致命错误时将错误文件保存在 /tmp/com.tinem/jvm_error/log/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}.log 路径下
# --add-opens java.base/java.lang=ALL-UNNAMED
# --add-opens java.base/sun.net.util=ALL-UNNAMED
# --add-opens java.base/java.lang.reflect=ALL-UNNAMED
# 因为我们的开发环境是jdk8,在jdk9以后有分模块的限制,通过这三个参数开放允许开发人员在不使用 exports 语句的情况下在 Java 标准库中访问公共类和接口。
# -Djava.security.egd是一个 Java 虚拟机(JVM)参数,用于指定用于生成随机数的设备。使用这个参数可以确保 Java 应用程序能够生成高质量的随机数,这对于加密和安全应用程序非常重要。
CMD mkdir -p /tmp/com.tinem/jvm_error/dumps/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}/ & \
 mkdir -p /tmp/com.tinem/jvm_error/log/${project.build.finalName} & \
 java ${signStart}JAVA_OPTS${signEnd} \
 -XX:+HeapDumpOnOutOfMemoryError \
 -XX:HeapDumpPath=/tmp/com.tinem/jvm_error/dumps/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}/ \
 -XX:ErrorFile=/tmp/com.tinem/jvm_error/log/${project.build.finalName}/${signStart}INSTANCE_NAME${signEnd}.log \
 --add-opens java.base/java.lang=ALL-UNNAMED \
 --add-opens java.base/sun.net.util=ALL-UNNAMED \
 --add-opens java.base/java.lang.reflect=ALL-UNNAMED \
 -Djava.security.egd=file:/dev/./urandom \
 -jar \
 /app/${project.build.finalName}.jar


# docker build -f classes/Dockerfile -t platform/${project.build.finalName}:test_oom .
#  docker run -v $(pwd)/tmp:/tmp --rm -it platform/${project.build.finalName}:test_oom
  1. 在微服务模块中引用配置
#platform-cloud/pom.xml

<plugin>                <!-- 共享配置文件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-remote-resources-plugin</artifactId>
                <version>1.7.0</version>
                <executions>
                    <execution>
                        <id>process-remote-resources</id>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                            <resourceBundles>
                                <resourceBundle>com.tinem:platform-config:${project.version}</resourceBundle>
                            </resourceBundles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
  1. 执行maven编译

maven install

编译后会在当前项目的class下生成Dockerfile文件

# 定义变量${ ,因为直接写${}会被转义,所以有些情况下我们想在生产的文件中输出${}就需要通过变量转义


# 采用alibaba的JDK 版本是:17.0.3.0.3
FROM registry.cn-shanghai.aliyuncs.com/fengzhihao/jdk:alibaba.17.0.3.0.3

# 创建工作文件夹
RUN mkdir /app

# project.build.finalName是maven插件的变量,用于获取编译后输出jar的名字
# 将maven编译后的jar添加到容器中
ADD platform-cloud-service-pay.jar /app/platform-cloud-service-pay.jar

# 默认jvm大小512M
ENV JAVA_OPTS=" -server \
 -Xmx512m \
 -Xms512m \
 -Xmn64m "

# 默认东八区
ENV TZ=Asia/Shanghai

# 创建jvm日志目录
RUN mkdir -p /tmp/com.tinem/jvm_error/dumps/platform-cloud-service-pay/${INSTANCE_NAME}/
RUN mkdir -p /tmp/com.tinem/jvm_error/log/platform-cloud-service-pay

# 切换工作文件夹
WORKDIR /app
# 容器运行时的命令
# mkdir -p /tmp/com.tinem/jvm_error/dumps/platform-cloud-service-pay/${INSTANCE_NAME}/
# mkdir -p /tmp/com.tinem/jvm_error/log/platform-cloud-service-pay
# 这两句是因为生产环境下会将/tmp目录挂载到单独的磁盘。导致容器创建的目录不存在,所以在容器启动时在创建一次
# -XX:+HeapDumpOnOutOfMemoryError 是 Java 虚拟机(JVM)的一个参数,用于在发生内存溢出错误时自动生成堆转储文件。
# -XX:HeapDumpPath  JVM 在发生内存溢出错误时将堆转储文件保存在 /tmp/com.tinem/jvm_error/dumps/platform-cloud-service-pay/${INSTANCE_NAME}/ 路径下
# -XX:ErrorFile JVM 在发生致命错误时将错误文件保存在 /tmp/com.tinem/jvm_error/log/platform-cloud-service-pay/${INSTANCE_NAME}.log 路径下
# --add-opens java.base/java.lang=ALL-UNNAMED
# --add-opens java.base/sun.net.util=ALL-UNNAMED
# --add-opens java.base/java.lang.reflect=ALL-UNNAMED
# 因为我们的开发环境是jdk8,在jdk9以后有分模块的限制,通过这三个参数开放允许开发人员在不使用 exports 语句的情况下在 Java 标准库中访问公共类和接口。
# -Djava.security.egd是一个 Java 虚拟机(JVM)参数,用于指定用于生成随机数的设备。使用这个参数可以确保 Java 应用程序能够生成高质量的随机数,这对于加密和安全应用程序非常重要。
CMD mkdir -p /tmp/com.tinem/jvm_error/dumps/platform-cloud-service-pay/${INSTANCE_NAME}/ & \
 mkdir -p /tmp/com.tinem/jvm_error/log/platform-cloud-service-pay & \
 java ${JAVA_OPTS} \
 -XX:+HeapDumpOnOutOfMemoryError \
 -XX:HeapDumpPath=/tmp/com.tinem/jvm_error/dumps/platform-cloud-service-pay/${INSTANCE_NAME}/ \
 -XX:ErrorFile=/tmp/com.tinem/jvm_error/log/platform-cloud-service-pay/${INSTANCE_NAME}.log \
 --add-opens java.base/java.lang=ALL-UNNAMED \
 --add-opens java.base/sun.net.util=ALL-UNNAMED \
 --add-opens java.base/java.lang.reflect=ALL-UNNAMED \
 -Djava.security.egd=file:/dev/./urandom \
 -jar \
 /app/platform-cloud-service-pay.jar


# docker build -f classes/Dockerfile -t core.harbor.fuletec.club/platform/platform-cloud-service-pay:test_oom .
#  docker run -v $(pwd)/tmp:/tmp --rm -it core.harbor.fuletec.club/platform/platform-cloud-service-pay:test_oom

INSTANCE_NAME是容器启动时的环境变量。因为一个项目可能会启动多个实例这是就需要通过INSTANCE_NAME来区分




单个项目编译成docker容器

<plugin>
				<groupId>com.spotify</groupId>
				<artifactId>dockerfile-maven-plugin</artifactId>
				<version>1.4.13</version>
				<configuration>
					<repository>platform/${project.artifactId}</repository>
					<tag>${build.number}</tag>
					<dockerfile>${project.build.directory}/classes/Dockerfile</dockerfile>
					<contextDirectory>${project.build.directory}</contextDirectory>
				</configuration>
</plugin>

这种方式是通过maven的一个插件将项目打包成docker镜像.

通过shell脚本打包docker容器并做git tag

每次打包添加git tag有助于我们快速定位问题。因为java报错一般会告诉你哪个文件的第几行报错。但如果我们的本地代码已经被修改会导致我们很难定位问题。这时如果我们容器的tag与git tag保持一致我们只需要查看容器的tag后从git拉取对于tag代码就可以很方便的定位问题


# bash.sh
#!/bin/bash
set -x
# params 1 repository core.harbor.xxx.com/harbor
# params 2 build_id

# nohup ./build.sh core.harbor.xxx.com/platform $(date +%Y%m%d_%H%M%S) > output.log 2>&1 &

# -Dmaven.compile.fork=true 参数,用以指明使用多线程进行编译;
# -Dmaven.test.skip=true 跳过测试代码的编译命令
# -T 1C 参数,表示使用每个 CPU 核心跑一个工程;

# docker 仓库地址
repositories="core.harbor.xxx.com/platform"

# 生成tag
tag=$(date +%Y%m%d_%H%M%S)

# 如果第一个参数不为空则将第一个参数是设置成仓库地址
if [ ! -n "$1" ]; then
  echo "repositories IS NULL"
else
  repositories=$1
  echo "repositories IS $repositories"
fi

# 如果第而个参数不为空则将第二个参数是设置成tag
if [ ! -n "$2" ]; then
  echo "tag IS NULL"
else
  tag=$2
  echo "tag IS $tag"
fi

# maven 编译
mvn clean install -T 1C -Dmaven.test.skip=true -Dmaven.compile.fork=true

# git tag
git tag "b_"$tag
# 推送git tag
git push origin "b_"$tag


project_root=$(pwd)

# 单个模块处理
buildProject(){
  echo "dsName $1"
  echo "dsNamespace $2"
  echo "project name $3"
  echo "project path $4"
  dsName=$1
  dsNamespace=$2
  projectName=$3
  projectPath=$4
  kind=$5

  cd ${project_root}/platform-cloud/${projectPath}/${projectName}/target
  # 编译docker镜像
  docker build -f classes/Dockerfile -t $repositories/${projectName}:$tag .
  # 推送镜像到docker镜像仓库
  docker push $repositories/${projectName}:$tag
  # 更新k8s
  kubectl -n ${dsNamespace} set image ${kind}  ${dsName} ${dsName}=$repositories/${projectName}:$tag

}

# platform-cloud-commons-admin 模块
buildProject platform-cloud-commons-admin platform-common platform-cloud-commons-admin platform-cloud-commons statefulset

# platform-cloud-service-channel 模块
buildProject p-c-s-channel platform-cloud-service platform-cloud-service-channel platform-cloud-service statefulset
buildProject p-c-s-link platform-cloud-service platform-cloud-service-link platform-cloud-service statefulset
buildProject p-c-s-message platform-cloud-service platform-cloud-service-message platform-cloud-service statefulset
buildProject p-c-s-network platform-cloud-service platform-cloud-service-network platform-cloud-service statefulset
buildProject p-c-s-security platform-cloud-service platform-cloud-service-security platform-cloud-service statefulset
buildProject p-c-s-pay platform-cloud-service platform-cloud-service-pay platform-cloud-service statefulset
buildProject p-c-s-user platform-cloud-service platform-cloud-service-user platform-cloud-service statefulset
buildProject p-c-s-data platform-cloud-service platform-cloud-service-data platform-cloud-service statefulset
buildProject p-c-s-task platform-cloud-service platform-cloud-service-task platform-cloud-service statefulset

buildProject p-c-w-auth platform-cloud-web platform-cloud-web-auth platform-cloud-web statefulset
buildProject p-c-w-notice platform-cloud-web platform-cloud-web-notice platform-cloud-web statefulset
buildProject p-c-w-gateway platform-cloud-web platform-cloud-web-gateway platform-cloud-web statefulset
buildProject p-c-w-link platform-cloud-web platform-cloud-web-link platform-cloud-web statefulset
buildProject p-c-w-netty platform-cloud-web platform-cloud-web-netty platform-cloud-web statefulset
buildProject p-c-w-file platform-cloud-web platform-cloud-web-file platform-cloud-web statefulset
buildProject p-c-w-tool platform-cloud-web platform-cloud-web-tool platform-cloud-web statefulset


相关推荐

如何使用Java API操作HDFS系统?(hdfs java api的常见环境准备?)

1.搭建项目环境打开Eclipse选择FileàNewàMavenProject创建Maven工程,选择“Createasimpleproject”选项,点击【Next】按钮,会进入“New...

DataX写插件开发-集成阿里云RocketMQ

在上一期我们对datax进行了技术调研DataX数据异构、数据同步神器,这一次我们集成一个RocketMQ写插件,能够非常方便对将mysql数据同步到MQ中,下面来总结下具体步骤。1.下载datax源...

以SpringMVC+Shiro+Mybatis为核心开发的精简后台系统源码分享

项目说明源码获取方式:关注转发之后私信回复【源码】即可免费获取到以SpringMVC+Shiro+Mybatis为核心开发的精简后台基础系统。包含用户管理,角色管理,部门管理,权限管理,菜单管理,日志...

手把手教小伙伴们使用 Nginx 部署 TienChin 项目!

今天我就来手把手教小伙伴们部署TienChin项目,一起把这个项目跑起来,看看到底是个什么样的项目。小伙伴们知道,对于这种前后端分离的项目,我们在实际部署的时候,可以按照前后端分离的方式来部署,也...

推荐一款超棒的SpringCloud 脚手架项目

之前接个私活,在网上找了好久没有找到合适的框架,不是版本低没人维护了,在不就是组件相互依赖较高。所以我自己搭建一个全新spingCloud框架,里面所有组件可插拔的,集成多个组件供大家选择,喜欢哪个用...

SpringCloud 微服务迁移到 Kubernetes 容器化完整流程

k8s容器部署流程具体步骤:第一步:熟悉SpringCloud微服务项目第二步:源代码编译构建第三步:构建项目镜像并推送到镜像仓库第四步:K8s服务编排第五步:部署服务所需的基础环境第六步:部署微服...

SpringBoot 实现动态配置及项目打包部署上线

一、动态配置文件我们需要了解Spring动态指定配置文件的方式,来提高我们的部署效率。1.1、概述在实际企业开发中,开发环境、测试环境、生产环境通常采用不同的数据库等中间件的连接方式。如果此时我们按照...

3.5 源码安装ONOS1.3.0(源码包怎么安装)

ONOS是由ON.Lab使用Java及Apache实现发布的首款开源的SDN网络操作系统,主要面向服务提供商和企业骨干网。近日笔者在学习ONOS的过程中写下了这篇文章,希望可以对刚接触ONOS的同学们...

jenkins+gitlab 实现自动化部署(jenkins配置git自动部署)

目录1、安装jdk,要记住安装路径2、安装maven,要记住安装路径3、安装git,要记住安装路径4、安装gitlab5、安装jenkins(centos7)创建安装目录下载通用war包启动和关闭Je...

CI&amp;CD落地实践6-Jenkins接入maven构建后端springboot项目

前言在前面一篇《CI&CD落地实践5-Jenkins分布式环境搭建及多节点运行》中,我们介绍了如何在Windows及Linux系统上部署Jenkins从节点,本章节介绍如何在Jenkins创建mave...

从0到1体验Jenkins+Docker+Git+Registry实现CI自动化发布

阅读目录:一、前言二、发布流程三、环境准备四、部署思路梳理五、三台机器上操作六、Git机器上操作七、Docker机器上操作八、Jenkins机器上操作九、上传JAVA项目代码到Git仓库十、Jenki...

微服务架构实战:使用Jenkins实现自动化构建

使用Jenkins实现自动化构建一个大型平台的微服务架构设计通常会产生很多项目工程,因此会有很多服务和应用需要部署,并且需要不断地迭代和更新,这是一个庞大的工程,所以我们需要借助自动化工具,实现各个微...

Jenkins 自动化部署实例讲解(jenkins自动化部署git 项目)

前言你平常在做自己的项目时,是否有过部署项目太麻烦的想法?如果你是单体项目,可能没什么感触,但如果你是微服务项目,相信你应该是有过这种感触的。这种情况下,我一般会劝你了解一下Jenkins这个玩意...

多模块的微服务项目容器化与Git追踪发布记录

在使用了微服务后,一个项目往往由多个模块组成,而容器化发布的建议是单个容器尽量只运行单个进程。所以我们会把每个模块单独打包成镜像运行。如果每个模块都单独配置Dockerfile会让我们维护起来很麻烦。...

手把手教你使用 Jenkins+Docker 实现持续集成

作者:乐之终曲来源:https://blog.csdn.net/qq_37143673/对于Jenkins我只能用两个字形容,难用。就不过多吐槽了,本篇是基于docker环境的使用。1.安...