Jenkins(环境变量、构建参数、流水线触发、通知报告)

文章目录

环境变量和构建参数

环境变量

环境变量基础

Jenkins支持在流水线中使用环境变量和参数,可以让流水线更加灵活

环境变量可以分为Jenkins内置变量和用户自定义变量两类

分类 详情
1. Jenkins 内置变量 定义:Jenkins 系统自带,全局可用,无需手动定义引用格式(3 种): 1. {env.\} 2. env.<ENV_VAR_NAME> 3. ${ENV_VAR_NAME}核心特性:以 "env." 为前缀,是 Pipeline 与 Jenkins 系统交互的媒介 注意事项:变量名固定(全大写 + 下划线),不可修改
2. 用户自定义变量 定义:用户根据需求手动定义,可作用于单个 Pipeline 或全局 引用格式:同内置变量(需先定义再引用) 核心特性:灵活扩展,适配个性化场景 注意事项:避免与内置变量重名(重名时自定义变量覆盖内置)

获取内置变量和环境变量

  • Jenkins在不同作业类型通常都提供了获取系统内置环境变量的方法,下面的来自于自由风格作业Build Steps中"运行shell脚本"中的链接;
    • IP:8080/env-vars.html

自定义全局环境变量

自定义环境变量的功能与内置环境变量相同

系统管理 → 全局属性 → 环境变量

自定义环境变量与全局环境变量同名时,全局环境变量将被覆盖;这可能会引起错误,必要时,可为自定义环境变量使用固定的前缀,例如"_ _"等;

参数化构建

参数化构建的目标在于为流水线提供基于参数值的灵活构建机制,让一个流水线的定义可以适用于多种需求情形

  • 其功能与引用方式与环境变量类似
  • 在触发作业运行之时,需要向各参数赋值
常用参数 参数类型 说明
git git参数 获取代码仓库中的tag标签,获取版本号
choice 选项参数 列出选项 测试/生产 部署/回滚类似于case/if
string 字符串参数 记录功能
password 密码参数 设置DB_PASSWORD数据库密码
File 文件参数 构建时手动上传文件(配置文件、证书、依赖包)

[参数化构建]自由风格类型项目(Docker代码发布流程[前端])

角色 IP
gitlab(存放小鸟飞飞的代码) 10.0.0.121/172.16.1.121
jenkins(代码发布平台) 10.0.0.122/172.16.1.122
web01(web集群) 10.0.0.110/172.16.1.110
docker(harbor仓库) 10.0.0.116/172.16.1.116

流程

  1. 开发将前端代码(含 Dockerfile)推送到 Git 仓库(如 Gitee/GitLab)
  2. 运维 / 开发触发 Jenkins 自由风格项目的「立即构建」
  3. 弹出参数选择界面,选择配置好的参数(如:构建分支)
  4. Jenkins 拉取 Git 仓库中选定分支的前端代码到工作空间
  5. 执行预设 Shell 步骤:安装依赖(npm install)→ 前端构建(npm run build)→ 生成静态资源(dist 目录)
  6. 执行 Docker 构建:根据 Dockerfile 打包镜像(镜像名 = 参数指定版本)
  7. 推送镜像到制品库(harbor仓库)
  8. 连接目标环境服务器(参数指定的部署环境),拉取镜像并启动容器
  9. 构建完成,返回成功 / 失败状态,可查看日志排查问题

(1)环境准备

docker安装harbor仓库

shell 复制代码
#1.安装docker
#2.安装docker-compose
#3.设置https  本地配置证书、购买证书、免费证书
#4.下载
wget https://github.com/goharbor/harbor/releases/download/v2.14.1/harbor-offline-installer-v2.14.1.tgz

#5.解压
mkdir -p /server/docker/harbor
tar -zxvf harbor-offline-installer-v2.14.1.tgz -C /server/docker/
###解压你的证书文件到/server/docker/harbor/keys下
unzip 21673089_harbor.chenshiquan.xyz_nginx.zip  -d /server/docker/harbor/keys

#6.修改配置文件
cd /server/docker/harbor
cp -rf {harbor.yml.tmpl,harbor.yml}
vim harbor.yml
#修改如下内容
hostname: 你的域名/IP
  certificate: 公钥存放位置
  private_key: 私钥存放位置
harbor_admin_password: 密码

#7.设置hosts解析
cat >> /etc/hosts <<EOF
10.0.0.115 harbor.chenshiquan.xyz
EOF

#8.安装
./install.sh 

#9.防火墙放行相应端口

#10.上传项目所需镜像

harbor仓库添加凭证

jenkins安装docker(开启Docker API)、web安装docker

  • 开启docker api,通过jenkins插件,通过docker api
  • jenkins配置docker(cloud)
  • 运行dockerfile的时候交给docker插件即可(替代了docker build、docker tag、docker login、docker push)
  • harbor镜像仓库
  • 也可以不使用jenkins的docker image插件,需要在shell中执行(docker build docker login docker tag docker push...)操作
shell 复制代码
#0.删除系统已有的runc
rm -rf /usr/local/bin/runc
#1.下载docker27.0.3二进制包到/download下
wget https://download.docker.com/linux/static/stable/x86_64/docker-27.0.3.tgz -P /download
#2.解压docker27.0.3二进制包,将包中的命令复制到/usr/local/bin/下
tar -xf /download/docker-27.0.3.tgz  -C /download
cp -rf /download/docker/* /usr/local/bin/
chown -R root:root /usr/local/bin/*
#3.查看docker版本
docker --version
#4.配置docker systemd文件
cat > /lib/systemd/system/docker.service <<'EOF'
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
Environment=GOTRACEBACK=crash
#Environment=HTTP_PROXY=10.0.0.1:7890  HTTPS_PROXY=10.0.0.1:7890

#注意二进制文件位置,开启Docker API
ExecStart=/usr/local/bin/dockerd  -H unix:///var/run/docker.sock -H 172.16.1.122:2375
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target
EOF
#5.设置镜像加速
mkdir  /etc/docker
cat >/etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors" : ["https://do.nark.eu.org",
   "https://dc.j8.work",
   "https://docker.m.daocloud.io",
   "https://dockerproxy.com",
   "https://docker.mirrors.ustc.edu.cn",
   "https://docker.nju.edu.cn",
   "https://docker.mirrors.ustc.edu.cn",
   "https://docker.registry.cyou",
   "https://docker-cf.registry.cyou",
   "https://dockercf.jsdelivr.fyi",
   "https://docker.jsdelivr.fyi",
   "https://dockertest.jsdelivr.fyi",
   "https://mirror.aliyuncs.com",
   "https://dockerproxy.com",
   "https://mirror.baidubce.com",
   "https://docker.m.daocloud.io",
   "https://docker.nju.edu.cn",
   "https://docker.mirrors.sjtug.sjtu.edu.cn",
   "https://docker.mirrors.ustc.edu.cn",
   "https://mirror.iscas.ac.cn",
   "https://docker.rainbond.cc",
   "https://do.nark.eu.org",
   "https://docker.shootchat.top",
   "https://registry.docker-cn.com"]
}
EOF

#6.生效系统配置文件,开启并开自启docker
systemctl daemon-reload && systemctl enable --now docker

#7.测试是否能拉取镜像
docker run hello-world
#8.查看镜像
docker images
#9.docker补全
yum install -y bash-completion
sudo curl -L https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
source /etc/profile.d/bash_completion.sh

#10.安装python3-docker让ansible支持docker模块
yum install -y python3-docker

#11.jenkins编写playbook
cat > /ansible/playbook/03-docker-china-ex-main.yaml <<'EOF'
- hosts: web
  tasks:
    - name: "0.安装docker模块python库"
      yum:
        name: "python3-docker"
        state: present
    - name: "1.删除docker容器"
      docker_container:
        name: "china_ex_main"
        image: "harbor.chenshiquan.xyz/library/china-ex-main:{{ git_tag }}"
        state: absent
    - name: "2.启动docker容器" 
      docker_container:
        name: "china_ex_main"
        image: "harbor.chenshiquan.xyz/library/china-ex-main:{{ git_tag }}"
        ports: ["8081:80"]
        state: started
        restart_policy: always
EOF

jenkins web上添加docker(cloud)

(2)gitlab新建代码仓库

(3)模拟开发上传前端代码到gitlab仓库(内含dockerfile)

shell 复制代码
#0.在gitlab上传公钥(使用Linux就上传Linux的公钥,windows就上传windows的公钥)
cat ~/.ssh/id_ed25519.pub
#1.上传china-ex-main zip文件

#2.编写dockerfile
cat > Dockerfile <<'EOF'
FROM  harbor.chenshiquan.xyz/library/node:16-alpine AS frontend
ENV CODE=/app/code/china/
RUN mkdir -p ${CODE}
WORKDIR ${CODE}
COPY china-ex-main ./
RUN set -e ;\
    npm install ;\
    npm run build
FROM harbor.chenshiquan.xyz/library/nginx:1.24
LABEL author="csq" destcation="前端中国制霸"
COPY --from=frontend /app/code/china/dist/* /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
EOF

#3.Git本地配置
git config --global user.name 'csq'
git config --global user.email '2033717617@qq.com'
git config --global color.ui true 
#4.初始化仓库
git init
#5.关联gitlab远程仓库(记得域名解析)
git remote add origin git@gitlab.chenshiquan.xyz:root/docker-china-ex-main.git
#6.上传代码
git add .
git commit -m 'docker china-ex-main code'
git push -u origin master
#7.上传标签
git tag -a 'v0.99' -m 'china-ex-main v0.90 add code'
#8.上传指定标签
git push origin  v0.99

(4)jenkins创建任务并build

(5)浏览器访问web

(6)模拟开发更新代码

修改zip里面的文件

shell 复制代码
git add .
git commit -m 'new code'
git push -u origin master
git tag -a "v1.0" -m "new code v1.0"
git push -u origin v1.0

(7)jenkins再次build,访问web是否改变

[参数化构建]自由风格类型项目(Docker代码发布流程[后端])

(1)环境准备

shell 复制代码
#0.jenkins开启Docker API
#1.准备dockerfile所需基础镜像
maven:3-eclipse-temurin-11-alpine
tomcat:9.0-jdk8
#2.jenkins准备ansible环境
cat > /ansible/playbook/04-java-hello.yaml <<'EOF'
- hosts: web
  tasks:
    - name: "0.安装docker模块python库"
      yum:
        name: "python3-docker"
        state: present
    - name: "1.删除docker容器"
      docker_container:
        name: "java_hello"
        image: "harbor.chenshiquan.xyz/library/java-hello:{{ git_tag }}"
        state: absent
    - name: "2.启动docker容器" 
      docker_container:
        name: "java_hello"
        image: "harbor.chenshiquan.xyz/library/java-hello:{{ git_tag }}"
        ports: ["8082:8080"]
        state: started
        restart_policy: always
EOF

(2)gitlab新建代码仓库

(3)模拟开发上传前端代码到gitlab仓库(内含dockerfile)

shell 复制代码
#0.在gitlab上传公钥(使用Linux就上传Linux的公钥,windows就上传windows的公钥)
cat ~/.ssh/id_ed25519.pub
#1.解压java-hello zip文件到docker-java-hello
###工作目录
mkdir -p src
unzip hello-world-war-src-code.zip -d src/docker-java-hello
cd src


#2.编写dockerfile
cat > Dockerfile <<'EOF'
FROM harbor.chenshiquan.xyz/library/maven:3-eclipse-temurin-11-alpine AS build
ENV CODE_DIR=/app/code
WORKDIR ${CODE_DIR}
COPY settings.xml /usr/share/maven/conf/
COPY  docker-java-hello  ./
RUN  mvn clean package

FROM harbor.chenshiquan.xyz/library/tomcat:9.0-jdk8 
LABEL author=csq destcation="tomcat war包"
COPY --from=build /app/code/target/*.war webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh","run"]
EOF

#3.Git本地配置
git config --global user.name 'csq'
git config --global user.email '2033717617@qq.com'
git config --global color.ui true 
#4.初始化仓库
git init
#5.关联gitlab远程仓库(记得域名解析)
git remote add origin git@gitlab.chenshiquan.xyz:root/docker-java-hello.git
#6.上传代码
git add .
git commit -m 'docker java-hello code'
git push origin master
#7.上传标签
git tag -a 'v0.99' -m 'docker xzs v0.99 code'
#8.上传指定标签
git push origin  v0.99

(4)jenkins创建任务并build

(5)浏览器访问web

(6)模拟开发更新代码

修改index.jsp

shell 复制代码
git add .
git commit -m 'new code'
git push -u origin master
git tag -a "v1.0" -m "new code v1.0"
git push -u origin v1.0

(7)jenkins再次build,访问web是否改变

流水线的触发机制

触发任务

自动化的流水线作业会按照一定的规则自动启动并运行,这类的规则便是所谓的触发条件

默认支持的构建触发器,无需额外插件

触发器类型 核心详情(用途 + 触发逻辑 + 实操场景)
1. 定时构建(Build periodically) 🔹 核心用途:按固定时间周期自动构建(如每日凌晨全量构建、每周日备份构建) 🔹 触发逻辑:通过 Cron 表达式定义周期(格式:分 时 日 月 周) 🔹 实操场景:前端项目每晚 23 点自动构建测试环境(Cron:0 23 * * *);每周日凌晨 3 点构建生产环境镜像 🔹 关键格式:H/30 * * * *(每 30 分钟构建一次,H 避免集群任务同时触发)
2. 轮询 SCM(Poll SCM) 🔹 核心用途:按周期检查 Git/SVN 仓库是否有代码提交,有更新则触发构建 🔹 触发逻辑:通过 Cron 表达式定义轮询周期,Jenkins 定期拉取仓库,对比代码版本差异 🔹 实操场景:前端项目每 15 分钟检查 Git 仓库 dev 分支(Cron:H/15 * * * *),有代码提交则自动构建测试环境 🔹 注意:相比 WebHook,轮询有延迟,适合仓库无 WebHook 权限的场景
3. GitHub hook trigger for GITScm polling 🔹 核心用途:接收 GitHub 的 WebHook 通知,触发构建(无延迟,比轮询高效) 🔹 触发逻辑:GitHub 仓库配置 WebHook URL(Jenkins 任务的触发 URL),代码提交 / 合并时 GitHub 发送通知,Jenkins 接收后触发构建 🔹 实操场景:前端开发推送代码到 GitHub dev 分支,立即触发 Jenkins 构建 + 测试,快速反馈代码问题 🔹 配置要点:需在 GitHub 仓库→Settings→WebHooks 中添加 Jenkins 的触发 URL
4. 在其它工程构建后触发(Build after other projects are built) 🔹 核心用途:依赖其他 Jenkins 任务构建结果,实现 "上下游任务联动" 🔹 触发逻辑:配置依赖的任务名称(可多个),选择触发条件("依赖任务成功构建后""依赖任务构建完成后无论结果") 🔹 实操场景:前端项目依赖后端接口服务构建(后端服务构建成功后,前端自动构建并部署联调环境);基础镜像构建完成后,前端自动基于新镜像构建
5. 触发远程构建(Trigger builds remotely) 🔹 核心用途:通过远程 URL / 脚本触发构建(支持传递参数) 🔹 触发逻辑:配置 "身份验证令牌"(如FRONTEND_DEPLOY_2025),通过 URL 格式 http://jenkins-ip:8080/job/任务名/build?token=令牌&参数名=参数值 触发 🔹 实操场景:通过脚本批量触发多环境部署(如curl "http://jenkins-ip/job/frontend/build?token=FRONTEND_DEPLOY_2025&DEPLOY_ENV=prod");第三方系统(如运维平台)触发前端发布 🔹 安全要点:令牌需保密,避免泄露导致恶意触发

插件扩展的构建触发器(需要安装对应插件)

触发器类型 核心详情(用途 + 触发逻辑 + 实操场景)
1. GitLab(GitLab CI/CD) 🔹 核心插件:GitLab Plugin 🔹 核心用途:接收 GitLab 仓库的 WebHook 通知,支持分支 / 标签过滤、合并请求触发 🔹 触发逻辑:GitLab 仓库配置 WebHook,代码提交、合并请求、标签创建时发送通知,Jenkins 按规则触发构建 🔹 实操场景:前端项目 GitLab 的 main 分支有合并请求时,自动构建并执行全量测试;创建 Git 标签(如 v1.0.0)时,自动构建生产环境镜像
2. Generic Webhook Trigger 🔹 核心插件:Generic Webhook Trigger Plugin 🔹 核心用途:接收任意系统的 WebHook 通知(支持自定义请求参数),适配非 GitLab/GitHub 的仓库 / 平台 🔹 触发逻辑:配置 WebHook 的触发路径、参数解析规则,第三方系统发送 HTTP 请求即可触发 🔹 实操场景:企业内部代码仓库、运维平台发送 WebHook,触发前端项目构建;接收测试平台通知,触发特定版本构建
3. GitHub Integration 🔹 核心插件:GitHub Integration Plugin 🔹 核心用途:深度集成 GitHub(比默认 GitHub Hook 更强大),支持 GitHub Actions 联动、分支保护规则校验 🔹 触发逻辑:绑定 GitHub 账号 / 仓库,配置触发事件(代码推送、Pull Request、标签创建) 🔹 实操场景:前端项目 GitHub 的 Pull Request 被审核通过后,自动构建并部署预发环境;GitHub Release 创建时,自动构建并上传制品
4. Parameterized Trigger 🔹 核心插件:Parameterized Trigger Plugin 🔹 核心用途:当前任务构建过程中,触发其他任务并传递参数(支持多任务串行 / 并行) 🔹 触发逻辑:在当前任务的构建步骤中添加 "Trigger/call builds on other projects",配置目标任务名称、传递的参数(如部署环境、镜像版本) 🔹 实操场景:前端构建完成后,触发 "前端部署任务",传递镜像版本参数(IMAGE_VERSION=${BUILD_NUMBER});构建任务触发 "测试任务",传递分支参数
5. URLTrigger 🔹 核心插件:URLTrigger Plugin 🔹 核心用途:监控指定 URL 的状态变化(如返回码、内容变化),触发构建 🔹 触发逻辑:配置监控 URL、检查周期、触发条件(如 URL 返回 200 且内容包含 "更新成功") 🔹 实操场景:监控后端接口文档 URL,当接口文档更新时(内容变化),触发前端项目构建(适配接口变更);监控制品库 URL,当新的基础镜像上传时,触发前端构建
6. MultiBranch Action Trigger 🔹 核心插件:MultiBranch Action Trigger Plugin 🔹 核心用途:多分支 Pipeline 中,某个分支构建完成后,触发其他分支 / 任务构建 🔹 触发逻辑:配置触发源分支(如 main 分支)、目标分支 / 任务,设置触发条件(成功构建后)🔹 实操场景:前端 main 分支构建成功后,触发 test 分支构建并执行回归测试;多模块项目中,公共模块分支构建完成后,触发所有依赖模块的分支构建

周期性构建

shell 复制代码
0 23 * * *  #每天晚上 23 点整构建一次
H/30 * * * * #每 30 分钟构建一次
0 H(3-4) * * 0 #每周日凌晨 3-4 点间随机小时、0 分构建一次
H(0,30) * * * *	 #每小时的 0 分或 30 分附近随机分钟构建(如 0 分 ±5 分钟、30 分 ±5 分钟)
特殊字符 含义 示例(结合前端场景)
* 匹配该字段所有有效值("每") * * * * * → 每分钟构建一次(仅测试用,避免生产使用);0 * * * * → 每小时 0 分构建
M-N 匹配从 M 到 N 的连续范围(闭区间) 0 22-23 * * * → 每晚 22 点、23 点整各构建一次(前端测试环境夜间验证)
M-N/X*/X 按步长 X 匹配范围(M-N 为指定范围,*为全范围) */15 * * * * → 每 15 分钟构建一次;H(0-30)/10 * * * * → 0-30 分钟内每 10 分钟构建一次(偏移随机)
A,B,Z 枚举多个离散值(逗号分隔) 0 3,23 * * * → 每天凌晨 3 点、晚上 23 点各构建一次;0 8 * * 1,3,5 → 每周一、三、五早 8 点构建
H(特有) 散列偏移(Hash):根据项目名称计算唯一偏移量,在字段范围内随机分配时间 H * * * * → 每小时随机某分钟构建(避免所有项目同时触发);H H(2-4) * * * → 每天 2-4 点间随机小时、随机分钟构建

upstream:由上游作业触发

若job-x依赖于job-y的执行结果,则称为job-y为job-x的upstream(上游)

Jenkins自2.22版本开始支持在triggers中定义upstream类型的触发条件;

  • 当前任务依赖到的upstream任务定义在upstreamProjects参数中,多个任务彼此间以逗号分隔;

  • 触发条件为upstream的执行状态

GitLab通知触发

GitLab通知触发,是指流水线关联的GitLab仓库上的代码出现变更时,由GitLab将相关事件经由Webhook通知给Jenkins,从而触发Jenkins执行指定Job的构建操作

代码仓库各分支上的流水线

Jenkins Server会自动从仓库中发现所有分支,并提取每个分支,而后根据Jenkinsfile运行pipeline

之后,每当git仓库上的任何分支发生新的代码变更时,Jenkins Server将自动触发相应的pipeline

流程

  1. gitlab开启内网访问
  2. 配置Jenkins项目可以由Gitlab上的事件触发
  3. Gitlab的代码仓库上配置Webhook
  4. 测试Push事件的自动触发

Gitlab自动化构建步骤

gitlab开启内网访问

以GitLab管理员的身份,设置系统在外发请求中,允许Webhook和服务对本地网络的请求

配置Jenkins项目可以由Gitlab上的事件触发

Gitlab的代码仓库上配置Webhook

测试Push事件的自动触发

通知与报告

Jenkins通知:将任务的执行状态、事件或信息推送给相关用户,这些通常发生在pipeline的"构建后处理时期

使用邮件通知

配置邮件功能

在设置->system中找到相关内容进行修改

记得保存

测试Email通知功能

在流水线上添加"构建后操作"

  • 在"构建后操作"里选择"E-mail Notification"即可在流水线上启用Email通知功能

构建测试

正确

错误

使用钉钉通知

安装dingtalk插件

流程

  1. 在接收构建通知的钉钉群上,创建机器人
  2. 在Jenkins上部署DingTalk插件
  3. 在Jenkins上的系统管理中,配置钉钉
  4. 在Jenkins流水线上,配置使用DingTalk进行构建通知

(1)配置钉钉群机器人

  • 配置钉钉群机器人的方法
    • 群设置->智能群助手->添加机器人->自定义

(2)配置Jenkins的DingTalk插件

  • 在Jenkins上安装DingTalk插件;

  • 而后配置钉钉插件

  • Manage Jenkins → Configure System → 钉钉

(3)在Jenkins流水线上,配置使用DingTalk进行构建通知

测试

使用Wechat通知

流程

  1. 在接收构建通知的企业微信群上,创建机器人
  2. 在Jenkins上部署"Qy Wechat Notification"插件
  3. 在Jenkins流水线上,在"构建后操作中"配置使用企业微信进行通知

(1)配置企业微信群上的机器人,并获取其Webhook

(2)在Jenkins上部署"Qy Wechat Notification"插件

(3)在Jenkins流水线上,在"构建后操作中"配置使用企业微信进行通知

构建并查看企业微信

相关推荐
运维@小兵2 小时前
Spring AI系列——开发MCP Server和MCP Client(SSE方式)
java·人工智能·spring
有一个好名字2 小时前
设计模式-代理模式
java·设计模式·代理模式
IT 行者2 小时前
Spring Security 7.0 迁移指南
java·数据库·spring
okseekw2 小时前
Java多线程开发实战:解锁线程安全与性能优化的关键技术
java·后端
Java天梯之路2 小时前
Spring Boot 钩子全集实战(三):`EnvironmentPostProcessor` 详解
java·spring
无敌最俊朗@2 小时前
STL-适配器(面试复习4)
java·面试·职场和发展
Han.miracle2 小时前
《Spring MVC 响应机制综合实践:页面、数据、JSON 与响应配置》
java·spring·springboot
JHC0000002 小时前
dy直播间评论保存插件
java·后端·python·spring cloud·信息可视化
凤凰战士芭比Q2 小时前
Jenkins(分布式、用户管理)
运维·分布式·jenkins