当前位置: 首页 > news >正文

A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战

  • 服务容器化构建的环境配置
  • 构建前需要解决什么
  • 下面我们带着问题分析构建的过程:
    • 1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?
    • 2. 构建之前动态修改项目的环境变量
    • 3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服务器磁盘暴满,导致资源浪费。此时我们在构建之前也要执行不可用的镜像清除操作;
    • 4. 本地LLama大模型服务地址,如何以容器部署时作为参数传入?
    • 5. 单工程服务和多工程服务如何合并成一个构建方案?
    • 6. 服务构建重复性校验
    • 7. 构建本次服务的镜像
    • 8. 缓存签名信息
  • 构建服务的完整脚本(build.sh)
  • 介绍了脚本构建的执行过程,下面jenkins端是如何进行配置的
  • 构建成功会在harbor仓库中显示相应的产物
  • 总结

下面我们接着上一篇文章《A6.Springboot-LLama3.2服务自动化构建(三)——编写Pipeline构建仓库初始化脚本》继续往下分析,编写Pipeline构建脚本。

服务容器化构建的环境配置

  1. 准备平台
    • 容器私有仓库Harbor的账号与密码,Harbor的安装与部署请参考我前面的文章《Harbor容器镜像私有仓库部署(For Liunx)》
  2. 构建主机
    • 安装xmlstarlet、jq工具;
      #主要用于项目的pom.xml文件解析
      apt install xmlstarlet
      #主要用于harbor仓库检测镜像时返回json数据的解析
      apt install jq
      
    • Docker容器管理工具安装,这个可以参考我前面的文章《Liunx安装Docker容器化管理工具(记录篇)》
  3. 部署主机
    • Docker容器管理工具安装,这个可以参考我前面的文章《Liunx安装Docker容器化管理工具(记录篇)》

构建前需要解决什么

  • 本地LLama大模型服务地址,如何以容器部署时作为参数传入?
  • 单工程服务和多工程服务如何合并成一个构建方案?
  • 如何解决jenkins执行环境与shell脚本执行环境不一致问题?
  • 构建成功后如何将容器上传到harbor镜像仓库中?

下面我们带着问题分析构建的过程:

1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?

在jenkins构建过程中由于平台用户环境与sh脚本执行环境不是同一个权限,为了解决这个问题网上有些解决方案说将当前用户添加到Admin Group当中,还有些通过安装SSH plugin登录到远程主机来执行来解决脚本调度过程中的权限问题。这里我们通过在Pipeline使用证书远程登录到相应的主机再执行相应逻辑:

def remote = [:]
remote.name = "${BUILD_HOST}"
remote.host = "${BUILD_HOST}"
remote.port = Integer.parseInt("${BUILD_PORT}")
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(credentialsId: "${DEPLOY_HOST_CREDENTIALS_ID}", keyFileVariable: 'identity', usernameVariable: 'username')]) {remote.user = usernameremote.identityFile = identitysshCommand remote: remote, command: "/bin/bash 这里执行你的远程脚本"
}

2. 构建之前动态修改项目的环境变量

利用xmlstarlet动态修改项目pom.xml中的环境变量配置

<properties><!--dev:开发环境;test:测试环境;pre:预发环境;prod:正式环境;--><project.env.tag>dev</project.env.tag>
</properties>
#其中project_dir为项目根目录,jenkins脚本配置中传入
$(xmlstarlet ed --inplace -N ns=http://maven.apache.org/POM/4.0.0 -u "/ns:project/ns:properties/ns:project.env.tag" -v "$env" "$project_dir/pom.xml")

只要替换pom.xml中配置的值,在application.yml我们就可以通过@project.env.tag@方式来获取;

spring:profiles:active: @project.env.tag@

3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服务器磁盘暴满,导致资源浪费。此时我们在构建之前也要执行不可用的镜像清除操作;

docker image prune -a --force

4. 本地LLama大模型服务地址,如何以容器部署时作为参数传入?

有时我们在部署某些docker容器时直接传入一些环境变量来达到相应参数的赋值。那么在我们开发的服务当中,如果打包成docker镜像也实现两样的效果应该怎么去配置呢,继续往下看阐述具体的步骤。

在Springboot服务配置文件application.yml中添加自定义配置(这里以llama主机地址为例)

llama:service:host: ${LLAMA_HOST:@llama.host@}

在这里插入图片描述
根据结构原理分析打包镜像后,我们只要在docker run之后添加-e LLAMA_HOST=xxx变量即可实现将参数值赋值到程序内部对应的配置中。

5. 单工程服务和多工程服务如何合并成一个构建方案?

配置jenkins服务构建时,我们希望无论是单工程形式还是多工程模块服务形式,脚本构建的过程是同一段打包逻辑。基于这一点考虑,是否只要将要打包的服务名放入一个数组中,然后循环依次构建对应的服务,这样无论是父工程方式还是单工程方式就不受影响了。

在项目中新建servers.sh来定义要构建的服务集合

#!/bin/bash
declare -a service_array
service_array=("ey-gateway" "ey-device")

在脚本中偏历service_array依次构建服务

#导入项目定义的数组,project_dir为项目根目录
source "${project_dir}/servers.sh"
for service in "${service_array[@]}"; do#移除每个服务对应的前缀作为构建服务名last_element=$(echo "$service" | cut -d'-' -f2-)#这里处理每个服务的构建逻辑
done

6. 服务构建重复性校验

当项目在迭代的过程开发人员每提交一个小版本以及测试工程师需要功能测试、单元测试和集成测试等,每个小间段都需要进行打包,构建次数会非常频繁。大部分情况测试人员需要构建项目时,往往是项目配置或代码逻辑没做任何改动的,难道jenkins在构建服务镜像时每次都需要重新构建会不会显得资源有点浪费(或者说是无意义构建)。那么有没有办法解决呢,即开发人员提交更改后执行打包才重新构建,如果没有做任何更改或项目版本号没有发生任务变量执行打包不重新构建延用原有的镜像。下面我们来看一下具体的实现部分:

首先需要创建校验签名文件,用于记录上一次构建的镜像签名值、版本号、镜像服务名等信息;在下次构建时作为比较的相关维度

#在上一步for循环前定义签名文件存储路径,以便之后的信息写入
#organization:组织机构名称,主要在harbor镜像仓库中用于区分不同公司或不同项目构建的服务,该参数值由jenkins平台端传入
build_sign_file=".${organization}_build_sign_config.ini"
for service in "${service_array[@]}"; do#这里处理每个服务的构建逻辑
done

取出当前服务的md5与上一次签名进行比较是否一致,如果不一致则进行构建动作,否则进行下一个条件判断

#通过服务的几个指标,计算出服务md5值:服务根目录下所有文件、服务iml后缀文件、如果存在HELP.md如果发生改变、如果存在mvn后缀文件且有发生改变、如果存在mvnw文件且有发生改变,根据这些指标重新计算md5值并写入到md5sums.txt文件中
find "$service" -type f -print0 | grep -vFz "$project_dir/$service/$service.iml" | grep -vFz "$project_dir/$service/HELP.md" | grep -vFz "$project_dir/$service/.mvn" | grep -vFz "$project_dir/$service/mvnw" | xargs -0 md5sum >md5sums.txt#取出md5sums.txt文件中的md5值
current_md5=$(awk '{print $1}' md5sums.txt | sort | md5sum)#将md5去掉连接符,作为当前要构建的服务签名值
current_environment_md5=$(tr -d ' -' <<<"$current_md5")#当前我们得到签名值后,将md5sums.txt临时文件移除
rm -rf md5sums.txt#如果首次执行或本地签名缓存文件不存在需要创建它
if [[ ! -f "$user_dir/${build_sign_file}" ]]; thentouch "$user_dir/${build_sign_file}"
fi#从签名文件中取出上一次构建对应服务的签名值,其中JENKINS_DEPLOY_HOME为环境变量值,即脚本根目录
#$user_dir/${build_sign_file}:表示将签名文件存储在用户目录下
#${service}_${env}_md5:以服务名称+环境+md5作为key存储
#其中kvs.py为python实现的操作本地文件的key=value类型的文件数据
old_environment_md5=$(python3 "${JENKINS_DEPLOY_HOME}/kvs.py" "take" "$user_dir/${build_sign_file}" "${service}_${env}_md5")

根据服务从harbor镜像仓库中查找一下看是否存在,如果不存在则进行构建动作,否则进行下一个条件判断

相关文章:

A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战

服务容器化构建的环境配置构建前需要解决什么下面我们带着问题分析构建的过程:1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?2. 构建之前动态修改项目的环境变量3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服…...

飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由(如何解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 飞牛NAS虚拟机安装爱快教程 📒🛠️ 前期准备🌐 网络要求💾 下载爱快镜像🚀 开始安装💻 开启IOMMU直通🌐 配置网络🚨 解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题➕ 创建虚拟机🎯 安装ikuai💻 进…...

蓝桥杯例题四

每个人都有无限潜能&#xff0c;只要你敢于去追求&#xff0c;你就能超越自己&#xff0c;实现梦想。人生的道路上会有困难和挑战&#xff0c;但这些都是成长的机会。不要被过去的失败所束缚&#xff0c;要相信自己的能力&#xff0c;坚持不懈地努力奋斗。成功需要付出汗水和努…...

八股——Java基础(四)

目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗&#xff1f; 7. Arra…...

CVE-2023-38831 漏洞复现:win10 压缩包挂马攻击剖析

目录 前言 漏洞介绍 漏洞原理 产生条件 影响范围 防御措施 复现步骤 环境准备 具体操作 前言 在网络安全这片没有硝烟的战场上&#xff0c;新型漏洞如同隐匿的暗箭&#xff0c;时刻威胁着我们的数字生活。其中&#xff0c;CVE - 2023 - 38831 这个关联 Win10 压缩包挂…...

【自然语言处理(NLP)】深度循环神经网络(Deep Recurrent Neural Network,DRNN)原理和实现

文章目录 介绍深度循环神经网络&#xff08;DRNN&#xff09;原理和实现结构特点工作原理符号含义公式含义 应用领域优势与挑战DRNN 代码实现 个人主页&#xff1a;道友老李 欢迎加入社区&#xff1a;道友老李的学习社区 介绍 **自然语言处理&#xff08;Natural Language Pr…...

Linux 命令之技巧(Tips for Linux Commands)

Linux 命令之技巧 简介 Linux ‌是一种免费使用和自由传播的类Unix操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年10月5日首次发布。Linux继承了Unix以网络为核心的设计思想&#xff0c;是一个性能稳定的多用户…...

【文星索引】搜索引擎项目测试报告

目录 一、项目背景二、 项目功能2.1 数据收集与索引2.2 API搜索功能2.3 用户体验与界面设计2.4 性能优化与维护 三、测试报告3.1 功能测试3.2 界面测试3.3 性能测试3.4 兼容性测试3.5 自动化测试 四、测试总结4.1 功能测试方面4.2 性能测试方面4.3 用户界面测试方面 一、项目背…...

低代码系统-产品架构案例介绍、轻流(九)

轻流低代码产品定位为零代码产品&#xff0c;试图通过搭建来降低企业成本&#xff0c;提升业务上线效率。 依旧是从下至上&#xff0c;从左至右的顺序 名词概述运维层底层系统运维层&#xff0c;例如上线、部署等基础服务体系内置的系统能力&#xff0c;发消息、组织和权限是必…...

二叉树(补充)

二叉树 1.二叉树的基本特性2.堆2.1.堆的基本概念2.2.堆的实现2.2.1.基本结构2.2.2.堆的初始化 2.2.3.堆的销毁2.2.4.堆的插入2.2.5.取出堆顶的数据2.2.6.堆的删除2.2.7.堆的判空2.2.8.堆的数据个数2.2.9.交换2.2.10.打印堆数据2.2.11.堆的创建2.2.12.堆排序 1.二叉树的基本特性…...

(DM)达梦数据库基本操作(持续更新)

1、连接达梦数据库 ./disql 用户明/"密码"IP端口或者域名 2、进入某个模式&#xff08;数据库,因达梦数据库没有库的概念&#xff0c;只有模式&#xff0c;可以将模式等同于库&#xff09; set schema 库名&#xff1b; 3、查表结构&#xff1b; SELECT COLUMN_NAM…...

CRM 微服务

文章目录 项目地址一、项目地址 教程作者:教程地址:代码仓库地址:所用到的框架和插件:dbt airflow一、 用户与认证服务 主要功能: 用户注册、登录、注销。 认证(OAuth、JWT 等)。 权限和角色管理(RBAC/ABAC)。 单点登录(SSO)。 技术亮点: 集成第三方身份认证(如 …...

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先&#xff0c;要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理&#xff0c;还是其他功能&#xff1f;明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时&#xff0c;你需要选择适合的编程语言、…...

DBSyncer开源数据同步中间件

一、简介 DBSyncer(英[dbsɪŋkɜː(r)]&#xff0c;美[dbsɪŋkɜː(r) 简称dbs)是一款开源的数据同步中间件&#xff0c;提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景。支持上传插件自定义同步转换业务&#xff0c;提供监控全量…...

< OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对

信息来源&#xff1a; 文件&#xff1a;/var/log/auth.log 因为在 sshd_config 配置文件中&#xff0c;已经定义 LogLevel INFO 部分内容&#xff1a; 2025-01-27T18:18:55.68272708:00 jpn sshd[15891]: Received disconnect from 45.194.37.171 port 58954:11: Bye Bye […...

react-bn-面试

1.主要内容 工作台待办 实现思路&#xff1a; 1&#xff0c;待办list由后端返回&#xff0c;固定需要的字段有id(查详细)、type(本条待办的类型)&#xff0c;还可能需要时间&#xff0c;状态等 2&#xff0c;一个集中处理待办中转路由页&#xff0c;所有待办都跳转到这个页面…...

1. Java-MarkDown文件创建-工具类

Java-MarkDown文件创建-工具类 1. 思路 根据markdown语法&#xff0c;拼装markdown文本内容 2. 工具类 import java.util.Arrays; import java.util.List;/*** Markdown生成工具类* Author: 20004855* Date: 2021/1/15 16:00*/ public class MarkdownGenerator {private Str…...

全连接神经网络(前馈神经网络)

一、全连接神经网络介绍 在多层神经网络中&#xff0c; 第 N 层的每个神经元都分别与第 N-1 层的神经元相互连接。 1、神经元 这个神经元接收的输入信号为向量 &#xff0c; 向量为输入向量的组合权重&#xff0c; 为偏置项&#xff0c; 是一个标量。 神经元的作用是对输入向…...

【llm对话系统】什么是 LLM?大语言模型新手入门指南

什么是 LLM&#xff1f;大语言模型新手入门指南 大家好&#xff01;欢迎来到 LLM 的奇妙世界&#xff01;如果你对人工智能 (AI) 的最新进展&#xff0c;特别是那些能像人类一样阅读、写作甚至进行对话的 AI 感兴趣&#xff0c;那么你来对地方了。这篇文章将带你认识 LLM 的基…...

【Linux】互斥锁、基于阻塞队列、环形队列的生产消费模型、单例线程池

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 1、互斥锁2、生产消费模型2.1 阻塞队列2.2 环形队列 3、单例线程池4、线程安全和重入问题 1、互斥锁 临界资源&#xff1a;多线程…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...