惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LangChain Blog
W
WeLiveSecurity
P
Proofpoint News Feed
月光博客
月光博客
NISL@THU
NISL@THU
L
LINUX DO - 最新话题
Webroot Blog
Webroot Blog
T
Threatpost
Y
Y Combinator Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Vercel News
Vercel News
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
MyScale Blog
MyScale Blog
N
News and Events Feed by Topic
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Help Net Security
Help Net Security
Recent Announcements
Recent Announcements
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
C
Cisco Blogs
雷峰网
雷峰网
量子位
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
I
Intezer
T
The Blog of Author Tim Ferriss
G
GRAHAM CLULEY
D
DataBreaches.Net
V
Vulnerabilities – Threatpost
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客

二丫讲梵

学习周刊-总第258期-2026年第15周 学习周刊-总第257期-2026年第14周 学习周刊-总第256期-2026年第13周 学习周刊-总第255期-2026年第12周 学习周刊-总第254期-2026年第11周 学习周刊-总第253期-2026年第10周 临时插播一条羊毛,免费领取450元大模型API代金券 学习周刊-总第252期-2026年第09周 学习周刊-总第251期-2026年第08周 学习周刊-总第250期-2026年第07周 学习周刊-总第249期-2026年第06周 诚邀评论,聊聊你所知欲知的我 学习周刊-总第248期-2026年第05周 我的QQ动态之2015年 我的QQ动态之2014年 我的QQ动态之2013年 我的QQ动态之2012年 我的QQ动态-2010-2011年 我的QQ动态-创栏小叙 学习周刊-总第247期-2026年第04周 Nexus社区版权益阉割--一文告诉你有哪些版本可以选择 学习周刊-总第246期-2026年第03周 学习周刊-总第245期-2026年第02周 学习周刊-总第244期-2026年第01周 学习周刊-总第243期-2025年第52周 学习周刊-总第242期-2025年第51周 开源项目ZenOps:带你领略禅意运维 学习周刊-总第241期-2025年第50周 用京东金融,享负债人生 学习周刊-总第240期-2025年第49周 学习周刊-总第239期-2025年第48周 整理我在静态服务透明代理上的极致求索之路,最后一个你绝想不到 学习周刊-总第238期-2025年第47周 我们输了,但收获颇多 太多了,太多了 学习周刊-总第237期-2025年第46周 学习周刊-总第236期-2025年第45周 学习周刊-总第235期-2025年第44周 二五年国庆二三事 学习周刊-总第234期-2025年第43周 学习周刊-总第233期-2025年第42周 学习周刊-总第232期-2025年第41周 学习周刊-总第231期-2025年第40周 学习周刊-总第230期-2025年第39周 西湖毅行 2025年开源世界逸闻三则 学习周刊-总第229期-2025年第38周 手抄《与妻书》 CNB开发与构建基于docker-cache缓存复用的配置实践心得 学习周刊-总第228期-2025年第37周 父亲善行录 学习周刊-总第227期-2025年第36周 带你认识我之看看我的高中同学录(其二) 学习周刊-总第226期-2025年第35周 带你认识我之看看我的高中同学录(其一) 认识神级MCP工具系列--用anyquery和数据库交互 学习周刊-总第225期-2025年第34周 学习周刊-总第224期-2025年第33周 学习周刊-总第223期-2025年第32周 学习周刊-总第222期-2025年第31周 学习周刊-总第221期-2025年第30周 CNB云原生开发环境届的瑞士军刀,详解qifei项目 vuepress-vdoing主题配置自建不蒜子统计 学习周刊-总第220期-2025年第29周 写在博客发表文章1000篇的节点 从claude cli的体验聊聊最大的敌人是我们自己的成见 学习周刊-总第219期-2025年第28周 学习周刊-总第218期-2025年第27周 学习周刊-总第217期-2025年第26周 理论正确,事实错误 学习周刊-总第216期-2025年第25周 学习周刊-总第215期-2025年第24周 学习周刊-总第214期-2025年第23周 学习周刊-总第213期-2025年第22周 学习周刊-总第212期-2025年第21周 从赵心童世锦赛夺冠聊聊我的斯诺克情缘 学习周刊-总第211期-2025年第20周 记录二五年五一之短暂回归家庭 学习周刊-总第210期-2025年第19周 学习周刊-总第209期-2025年第18周 学习周刊-总第208期-2025年第17周 Go开发实践之Gin框架将前端的dist目录embed到二进制 学习周刊-总第207期-2025年第16周 近期关于cobra库的一些实践心得总结 学习周刊-总第206期-2025年第15周 我的嗜好--嗑瓜子 记大宝参加幼儿园组织的清明烈士陵园扫墓活动 学习周刊-总第205期-2025年第14周 学习周刊-总第204期-2025年第13周 前端开发小笔记--在数组中给字段添加值与删除字段的操作 学习周刊-总第203期-2025年第12周 人生实苦,何以自渡 学习周刊-总第202期-2025年第11周 近期发现的一些优秀的工具提名(一) 学习周刊-总第201期-2025年第10周 学习周刊-总第200期-2025年第09周 记一次女友喝醉使我忍术破功 爱情风波--一次分手又复合的经历 学习周刊-总第199期-2025年第08周 整理我的信息源
Jenkins结合MySql Database插件的平台化实践思路
二丫讲梵 · 2022-09-05 · via 二丫讲梵

# 前言

以往 Jenkins 实践当中,配置了共享库的流水线方案,通过将核心公共逻辑抽离成膜版,项目个性化配置信息放到引导文件中的方式进行推进。

这种方案没有什么毛病,对于运维的维护工作也是比较友好的,只是后来我们打算再在 Jenkins 上层做一下平台化封装的时候,发现还是存在一些问题,并且有一些难度的。

最近我了解学习到了一个与 MySQL Database 插件结合的思路,能够比较好解决这种问题,那么接下来话不多说,直接进入正题,让我们来认识一下这个插件。

# 安装插件

安装如下两个插件:

因为 MySQL 的插件会需要依赖一个 database 的驱动,因此也要安装这个插件。

# 配置插件

插件成功安装之后,我们来到 系统管理 --->系统设置,然后搜索 database,可以看到数据库的配置项。

配置信息都比较常规,也就不一一介绍了,只需要在数据库当中创建一个 jenkins 库,然后按如下截图配置即可:

其中的测试语句为:select version();

如果点击 Test Connection 之后报如下错误:

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

1

则需要对 JDK 进行一点配置的调整:

$ vim /opt/java/openjdk/conf/security/java.security

# 将这行内容 jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \   中的 SSL 部分删去,改后的效果如下
jdk.tls.disabledAlgorithms=RC4, DES, MD5withRSA, \

1
2
3
4

然后重启 Jenkins,再次进行配置测试,应该就能通过了。

# 使用

配置完毕之后,我们就可以通过一个固定语句,在流水线当中,与数据库进行交互了。

比如我的项目需要的配置信息有如下内容:

那么就创建一个项目信息的表:

CREATE TABLE `job_msg` (
  `run_node` varchar(255) DEFAULT NULL,
  `service_name` varchar(255) DEFAULT NULL,
  `webroot_dir` varchar(255) DEFAULT NULL,
  `default_branch` varchar(255) DEFAULT NULL,
  `git_url` varchar(255) DEFAULT NULL,
  `hosts` varchar(255) DEFAULT NULL,
  `build_command` varchar(255) DEFAULT NULL,
  `free_command` varchar(255) DEFAULT NULL,
  `exclude_file` varchar(255) DEFAULT NULL,
  `build_base_image` varchar(255) DEFAULT NULL,
  `project_file_path` varchar(255) DEFAULT NULL,
  `robot_key` varchar(255) DEFAULT NULL,
  `job_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

然后存进去一条数据:

INSERT INTO `job_msg` (`run_node`, `service_name`, `webroot_dir`, `default_branch`, `git_url`, `hosts`, `build_command`, `free_command`, `exclude_file`, `build_base_image`, `project_file_path`, `robot_key`, `job_name`) VALUES ('master', 't-eryajf-blog.eryajf.net', '/data/www/${SERVICE_NAME}', 'main', 'https://jihulab.com/eryajf-jenkins/eryajf-blog.git', 'ALL\\n172.19.192.132', 'echo test', 'chown -R www.www /data/www/${SERVICE_NAME}/', 'ansible_tmp\\nansible_tmp@tmp\\n.git\\nnode_modules', 'eryajf/node:10.6', '.', '6a781aaf-0cda-41ab-9bd2-ed81ee7fc7d2', 'test-eryajf-blog');

1

此时我们把 job_name 字段作为该表的唯一标识,那么创建一个项目,就可以通过如下配置拿到对应的数据:

// 获取 job 信息
res = get_mysql_msg("${JOB_BASE_NAME}")
if ( res == []) { throw new Exception(" ${JOB_NAME}没有找到对应的项目信息 ") }
job_msg = get_job_msg(res)

// 判断是否已经具有 service_name  如果没有则通过jobname 赋值
if ( !job_msg.service_name ) {
    service_name = "${JOB_NAME}"
}

// 各个参数落位
env.RUN_NODE = "${job_msg.run_node}"
env.SERVICE_NAME = "${job_msg.service_name}"
env.WEBROOT_DIR = "${job_msg.webroot_dir}"
env.DEFAULT_BRANCH = "${job_msg.default_branch}"
env.GIT_URL = "${job_msg.git_url}"
env.HOSTS = "${job_msg.hosts}"
env.BUILD_COMMAND = "${job_msg.build_command}"
env.FREE_COMMAND = "${job_msg.free_command}"
env.EXCLUDE_FILE = "${job_msg.exclude_file}"
env.BUILD_BASE_IMAGE = "${job_msg.build_base_image}"
env.PROJECT_FILE_PATH = "${job_msg.project_file_path}"
env.ROBOT_KEY = "${job_msg.robot_key}"

pipeline {
    agent any
    stages {
        stage('# 构建开始') {
            steps {
                script{
                    sh "printenv"
                }
            }
        }
    }
}

// 拉取job在数据库中的信息
def get_mysql_msg(jobName) {
    println "===========获取${jobName}信息============"
    getDatabaseConnection(type: 'GLOBAL') {
        def result = sql("SELECT *  FROM job_msg WHERE job_name=\"${jobName}\"")
        return result
    }
}

// 格式化数据信息,返回的是map信息
def get_job_msg (res) {
    message = ""
    for (i in res) {
        if (i != "[" && i != "]") {
            message += i
        }
    }
    job_map = message.split(', ').collectEntries{it.replaceFirst(/:/, '000000').minus("]").minus("[").split('000000') as List}
    return job_map
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

其中的 get_mysql_msg() 方法就是通过项目名作为唯一标识,然后去数据库里拿到这个项目对应的其他匹配信息,再填充到整个构建流程当中。

同理,构建过程中,如果有需要往库里写数据的时候,比如要将当次构建的一些信息存库的话,仍然可以调用如下方式进行:

// 向数据库中插入本次构建记录
def set_job_history (buildId,platForm,jobName,branch,buildImage,messAge,build_user) {
    getDatabaseConnection(type: 'GLOBAL') {
        def result = sql("INSERT INTO `job_histoy` SET build_id='" + buildId + "',platform= '" + platForm + "',job_name= '" + jobName + "',branch= '" + branch + "',build_image= '" + buildImage + "',build_user='" + build_user + "',message= '" + messAge + "';")
    }
}

1
2
3
4
5
6

# 思路扩展

当我们已经捋顺了上边的思路之后,就可以把思路再打开一下。

一个项目的元数据信息,通过工单平台,由研发人员提交上来,经过审核之后,这份数据就会存在 MySQL 当中,然后 Jenkins 平台只需要创建一个 job_name 对应的项目,直接套入到这个模板即可,而不再需要关心维护其他数据了。