工程化实践:使用flyway进行数据库版本化

摘要 Flyway是一款数据库版本化工具。网上不少文章写的是将Flyway集成到Java应用中实现的。这种方式不适合工程化。本文介绍如何工程化的使用flyway进行数据库版本化。 如何理解Flyway Flyway进行版本化的逻辑非常简单。 在目标数据库中创建一个flyway_schema_history的表,用于记录数据库当前的版本。 当执行flyway migrate执行,根据config/flyway.conf配置中的连接信息连接到数据库。 检查sql目录的sql文件。sql文件名遵从flyway的命名约定。如果sql目录的版本比实际数据库中flyway_schema_history表里记录的版本要低,则执行升级版本的sql文件。 如果执行升级sql文件成功,则更新flyway_schema_history表中记录。 以上是个人理解flyway原理后,用大白话阐述出来的。大家可以看下官方介绍:https://flywaydb.org/getstarted/how sql文件的命名约定 执行样例 在安装完成flyway命令(下载地址)后,执行命令: flyway -configFiles=config/flyway.conf migrate 执行结果: Flyway Community Edition 6.5.5 by Redgate Database: jdbc:h2:file:./foobardb (H2 1.4) Successfully validated 0 migrations (execution time 00:00.009s) WARNING: No migrations found. Are your locations set up correctly? Creating Schema History table "PUBLIC"."flyway_schema_history" ... Current version of schema "PUBLIC": << Empty Schema >> Schema "PUBLIC" is up to date. No migration necessary. 与CI/CD集成 使用1个Git仓库对数据库工程进行版化。目录结构如下: ...

2020-09-06 · 1 min · 99 words · 翟志军 Jack Zhai

远程办公十分钟,干一个月的活,剩下的时间……

三年多前,一位国外的老哥在 stackexchange.com(国外的技术问答社区)上发表了一个问题。 问题大概内容就是远程工作的他是一名程序员,每个月他只需要花大约10分钟就完成整个月的工作了。这样的状态,他维持了6个月。公司也从来没有表示过对我的表现不满意,事实上,公司聘用他,并从他那得到了想要的。他的疑问是这样继续下去道德吗。 本文不想谈道德,而是从公司经营和团队管理角度开始谈。 公司经营角度 如果放他在公司里坐班,他能不能用10分钟完成一个月的工作呢?我们不知道。但是,如果他能做到,他会告诉上级领导吗? 我们也不知道。这里,我想问问坐班的读者,你会告诉你的上级吗? 站在公司经营的角度,公司当然期望10分钟做完以前1个月的工作,节约下来的人力成本可以做其他的事情。 这时,如果你是公司的经营者,你如何达到自己的期望呢? 国内某些公司的做法,似乎能避免国外老哥这种情况的发生。做法简单粗暴:设立KPI等级,同时每半年淘汰KPI倒数10%的人。 国外老哥想得到高的KPI等级,会主动告诉领导他的功劳。但是,现实会是这样吗? 这位老哥,并不一定要一次把1个月缩短到10分钟。他可以在评KPI前的一个星期,主动告诉领导他缩短几天的工作量就可以了。 职场里的老油条,应该能懂我说的话。在评KPI前告诉领导是为了让领导在评KPI时,能快速想起你的成绩(KPI真的很主观)。本来可以缩短1个月的,而你故意只缩短几天,是为了给自己下次评KPI留有余地。 现实可能更复杂。如果你是公司经营者,你会如何做呢? 团队管理角度 如果你是这位老哥的直接领导,你觉得是什么原因,一项工作本来只需要10分钟完成,你的团队却需要1个月? 你可能会怪这位老哥不“老实”。可是老哥一辈子不告诉你事实,你连“怪”的机会都没有。 你可能觉得这不是问题。因为手上人越多,你在公司里的份量就越大。 你可能根本就不知道自己的团队效率能提高那么多。 还有很多可能性。留给读者朋友自己体会。 问题到底是什么 说了这么多,关于这位老哥的案例,问题到底是什么? 不知道各位读者心里有没有问:他的工作内容是什么,为什么他的工作需要每个月重复。笔者认为这才是本案例的关键问题。 如果你深入问了,团队效率提升是自然而然发生的事情。让程序员每天做重复的事情,TA会很难受。否则你招的可能是一个假的程序员。 笔者认为:作为团队管理,通过发现“重复工作”来提高效率是一种常识。所以,如果有了这种常识,根本就不会发生本案例了。 如何让每位团队成员拥有这种常识,这是另一个议题。而如何让整家企业的人都有这样的常识,这又是另一个议题。 后记 过去到现在,笔者经常听到的一句话:“过程我不管,我只看结果”(也被人称为:结果导向)。这句话本身是正确的,但是,我们如果把团队管理者看作篮球队的教练,比赛中,你和你的队员一直盯着计分牌(结果),对于比赛最后得分是没有任何益处的。 是时候重新审视“以结果导向”在企业中带来的负作用了。

2020-08-02 · 1 min · 29 words · 翟志军 Jack Zhai

突发!!!Terraform、Consul、Vagrant等可以继续在中国使用!

昨天各种朋友、群,广泛传播以下信息: 重磅消息!!!Terraform、Consul、Vagrant等禁止中国使用! 我不清楚上面“Terms of Evaluation for HashiCorp Software”这个页面截图是什么时候的。HashiCorp旗下这么多软件,如上图。为什么他只圈Terraform、Consul、Vagrant?其它几款软件怎么不提?难道当时“Terms of Evaluation for HashiCorp Software”页面下文只提了Terraform、Consul、Vagrant? 以下是我的最新截图(2020-5-30 06:34 中国时间): 使用机器翻译如下: 请注意,“Terms of Evaluation for HashiCorp Software”最新版说的是Vault企业版 整件事情,我们其实更应该问HashiCorp的人,他们为什么做这样的决定。 以下是2020-5-3 6:43 北京时间截图: 原文链接:https://news.ycombinator.com/item?id=23349635 笔者使用机器翻译如下: 您好,我是HashiCorp的创始人,我想解释一下。 首先,本文档仅适用于企业评估软件。这不适用于我们的OSS软件,除非在注册企业评估的上下文中,否则不应将其链接到我们的OSS附近。 最重要的是:这为什么在这里?这不是政治声明。这是法律要求。我们在保险柜中使用的加密受中国出口管制法律的约束,并且(根据中国法律)我们在中国销售是非法的。 为了能够在中国销售保险柜,我们必须将可以在保险柜中使用的加密限制为政府可接受的版本。 我们不这样做,因此在中国销售是非法的。我们必须在企业术语中包括这一行。 编辑:我们的法律团队已更详尽地更新了我们的条款。您可以在此处的第二段中阅读更新的副本:https://www.hashicorp.com/terms-of-evaluation 最后结论,Terraform、Consul、Vagrant等可以继续在中国使用! 本文不是为了给HashiCorp洗白,其实别人也没故意黑。 最后,如果您觉得此文章说的是事实,请转发给更多的朋友,让他们看到事实。

2020-05-30 · 1 min · 38 words · 翟志军 Jack Zhai

Jenkins kubernates原理

如何使用 使用Kubernetes插件时,我们需要做三件事情: 根据官方文档,在Jenkins上加入kubernetes配置。 在Jenkinsfile中加入kubernetes agent的申明。 指定容器执行你的业务脚本。 关于第2点,kubernetes agent的申明又有两种方式。一种是脚本式的,代码样例如下: podTemplate(containers: […]) { node(POD_LABEL) { stage('Run shell') { container('mycontainer') { sh 'echo hello world' }}}} 一种是申明式,代码样例如下: pipeline { stages { stage('Run maven') { agent { kubernetes { yaml """ apiVersion: v1 kind: Pod metadata: labels: app: jenkins-agent spec: containers: - name: maven image: maven:alpine command: - cat tty: true - name: busybox image: busybox command: - cat tty: true """ }} steps { container('maven') { sh 'mvn -version' }}}}} 笔者推荐使用申明式。yaml配置部分看起来并不优雅,这是另一个话题。咱们今后再讲。 ...

2020-05-04 · 1 min · 150 words · 翟志军 Jack Zhai

使用 Jenkins + Ansible 实现跨应用配置管理

本文继续前两篇 Jenkins + Ansible 的文章(见附录)的例子。代码仓库结构与 《使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101》 介绍的相似。 但是以下改进: 增加了展示跨应用配置管理的样例(本文重点) 实现了二进制包与配置分离 跨应用配置是什么 《持续交付》的2.4.4节介绍了“跨应用配置管理”。但是书中没有明确给出它的定义。以下是笔者所理解的“跨应用配置”: 所谓跨应用配置指的是在同一个配置项同时被多个应用引用。 比如现实中同一个 Redis 的配置项(如地址、端口)就可能同时被多个业务系统引用。如下图所示。 为什么要进行跨应用的配置管理 如果没有跨应用配置的管理,我们就必须在应用1和应用2的配置文件中写死 redis 的配置项(在没有配置中心的情况下)。这样一看是没有问题的。但是笔者认为应用在到达10个以上的时候会(经常)遇到以下问题: 无法实现快速重建一整套新的环境。新的环境意味着新的 redis 地址。也意味着所有引用了 redis 地址的应用的配置都要改。手工修改很容易出错。 当你希望对现有的 redis 进行调整时,你无法评估影响面,因为你不知道哪些应用使用了这个 redis。进而,导致团队对架构优化的信心不足。 这两个问题会随着系统数量增加而加重。 那么如何实现跨应用的配置管理以解决上述问题呢? 如何实现跨应用的配置管理 如果使用如 Ansible、Puppet、Chef 这类自动化工具,跨应用的配置管理就很容易实现。因为它们的变量系统,天生就支持一处定义配置项,其它地方到处引用。对 Ansible 变量不熟悉的同学可以在文末找到学习链接。 在我们的 Nginx + Spring Boot 的例子中,对配置代码仓库(2-env-conf)进行了调整,结构如下: ├── Jenkinsfile ├── README.MD └── dev ├── group_vars │ ├── all # Ansible 默认的 all 组变量目录 │ │ └── global.yaml │ └── nginx.yaml # nginx 组变量 ├── host_vars │ ├── 192.168.52.10 │ └── 192.168.52.11 └── hosts 因为 Spring Boot 应用的端口会被 Nginx 的配置引用,所以,我们将端口的配置项放到 global.yaml 中,代码如下所示。 ...

2020-03-12 · 1 min · 191 words · 翟志军 Jack Zhai

如果张小龙谈 DevOps 平台

设计原则 张小龙谈微信: 我们没办法让10亿人来投票决定什么是好的,也投不出来。那怎么才能通过改变寻求设计的优化,让它变得更好呢?这个决策必须遵循好的设计原则。 张小龙谈 DevOps 平台: 我们没办法让所有研发团队来投票决定什么样的 DevOps 平台是好的,也投不出来。那怎么才能通过改变寻求设计的优化,让它变得更好呢?这个决策必须遵循好的设计原则。 我把这几个原则念给大家听下,大家可以对照 DevOps 平台来思考一下,会很有意思。 为软件的发布创建一个可重复且可靠的过程 将几乎所有的事情自动化 把所有的东西都纳入版本控制 提前并频繁地做让你感到痛苦的事 内建质量 “DONE” 意味着“已发布” 交付过程是每个成员的责任 持续改进 老翟插话:以上设计原则,是《持续交付》中1.6章节中写的。 做最好的工具与 996 张小龙谈微信: 一个用户每天的时间是有限的,这是次要的。最主要的是,技术的使命应该是帮助人类提高效率。 张小龙谈 DevOps 平台: 一个程序员每天的时间是有限的,这是次要的。最主要的是 DevOps 平台的使命应该是帮助研发团队提高软件发布的效率。 老翟插话:我的真实经历,当我问一个 DevOps 平台的设计人员为什么要把部署阶段设计得这么难用(效率低下)。得到的答案是怕用户部署错。这是使用老的思路来设计 DevOps 平台:如果一件事情容易出错,那我们就尽量少做。而让用户难用,就可以自然实现目的。 关于社交,关于 DevOps 本源 张小龙谈微信: 其实我们人的社交是没有发生改变的,或者说社交的需求并没有发生改变。我们在线上的社交只是线下的社交的一个映射而已。 张小谈 DevOps 平台: 其实我们研发团队的软件发布是没有发生改变的,或者说软件发布的需求并没有发生改变。我们在 DevOps 平台上的软件发布只是线下的软件发布的一个映射而已。 老翟插话:为什么开源类的 CI/CD 平台,Jenkins 占有率那么高?很大一部分原因是人们从原来的手工发布迁移到 Jenkins 上,非常的平滑,自然。纵观现在很多 DevOps 平台,把基本的构建编译的命令都隐藏起来,不允许用户轻松地看到或者修改。这是那些 DevOps 平台“难用”的原因之一。 什么是好的 DevOps 平台 张小龙谈微信: 我觉得一个好的产品不需要费口舌解释,我解释了这么多,说明我们做得不够好。 张小龙谈 DevOps 平台: 我觉得一个好的 DevOps 平台不需要费口舌解释,我解释了这么多,说明我们做得不够好。 ...

2020-01-03 · 1 min · 109 words · 翟志军 Jack Zhai

业务老大问 DevOps 改进半年后,会得什么确切结果?

要的是确切结果,不要忽悠我 前段时间,乔帮主(乔梁,《持续交付2.0》的作者)在持续交付2.0的群里发出这一句话: 业务老大问:“原来100工程师做的一个产品,用半年时间做 devops 改进。半年之后会得到什么确切的结果?” 以上是原话。 乔帮主在群发这话的意思是:如果你的业务老大问这样的问题,你该如何回答? 请注意,业务老大要的是确切结果,不要拿“虚”的东西来忽悠人。 请读者朋友思考一会。 。 。 。 客官不要急,请再思考一会鸭。 。 。 面对老大这样的提问,技术人可能觉得好笑,接着可能装作一本正经回答老大: 如果DevOps改进半年后,会使单元测试覆盖率提高到 80%。 如果DevOps改进半年后,会使A系统的部署耗时缩短到 1 分钟。 这回答真的很“确切”,但是,还是没有办法说服业务老大。注意,业务老大是不懂技术的。老大听到你的回答,估计一头雾水:什么是单元测试覆盖率?提高到 80% 后,对我的业务 KPI 又有什么关系? 别笑,这在 IT 行业里是常态。很多时候是不懂技术的老大,却又领导着一批技术人员。 面对这样的“常态”,作为技术人员,我们有必要,也有责任让不懂技术的业务老大理解 IT 行业里必要的“常识”。 回到业务老大的问题,如果你仔细思考,还真不好回答。比如,单元测试覆盖率提高到 80% 后,对我的业务 KPI 又有什么关系?能让我的业务 KPI 提高 80% 吗? 老翟的做法 当笔者看到这个问题,第一感觉就是:我们必须找到 DevOps 改进措施和业务老大关心的 KPI 之间的关系。换句话说,就是如果在100名工程师做一个产品的团队的情况下,进行 DevOps 改进半年后,会给我的业务 KPI 带来什么确切的结果? 笔者认为业务老大的问题,可以拆分成两个小问题: 有效性问题:如何证明 DevOps 改进是对业务 KPI 提升是有效的? 进度问题:怎么评估 DevOps 改进对业务 KPI 提升了多少? 如何证明 DevOps 改进是对业务 KPI 提升是有效的? 这就是我说的:我们必须找到 DevOps 改进措施和业务 KPI 之间的关系。 “DevOps 改进措施和业务 KPI 之间的关系”指的是什么?这需要针对不同的业务场景进行举例说明。 ...

2019-12-31 · 1 min · 168 words · 翟志军 Jack Zhai

从王垠面试阿里的事件看程序员招聘

餐饮行业里,有些饭店的服务员应聘是需要试工的。就是让应聘者穿上酒店的工作服,然后在工作繁忙时间,工作一段时间。 这段时间里,面试官可以观察到他在点菜时会不会与客人互动,上菜过程中的专业程度等。进而判断要不要录入他。 试工后,基础能回答这人能否胜任当前工作。 当然,“试工”对于招聘起到效果也取决于面试官。这是另一个问题了。 而 IT 行业,如果面试官不问个偏门算法,问个万万亿级流量的处理解决方案,似乎显得自己比面试者差。所以,IT 行业有个笑话:面试造火箭,入职拧螺丝。 我们是不是应该换个方式来招聘程序员?也用“试工”来遴选人才。 据我所知,ThoughtWorks 很多年前就已经采用“试工”的方式招人了。以下是笔者当时的面试经历: 一面是与 HR 简单聊聊。 二面,你必须在规定时间内完成一个家庭作业(需要写代码)。当你把作业交上去,HR 会找到公司内部的程序员帮忙看题(这样有助于缓和HR与程序员的关系,因为HR有求于程序员啊。)。 三面,他们会邀请你到办公室,然后HR找两个程序员和你结对编程(注意:这里是真实的上机写代码),内容就是在你交的作业的基础上加需求。过程中,他们会观察你,会提问你。 其实,整个三面的过程,就是试工的过程。虽然不能拿真实代码来改,但是也尽量模拟真实的工作场景:结对编程、别人对你代码的质疑等。 像 ThoughtWorks 这样试工的,在我们行业里,真的太少了。 回到阿里面试王垠(暂不说是不是受邀面试)这件事。 从赵海平的回复来看: 整个面试最关键的过程恰好是对简历上具体工作的详细了解,这个王垠在博客里完全没有提到,实际上我问了将近二十到三十分钟,我希望王垠能够意识到这部分才是面试真正考核的部分,应该尽量把自己最拿手最出彩的工作分享给面试官,详细解释为什么难,为什么有意义,为什么对公司有着深远的影响,而不是直接问面试官是做什么的,到底懂不懂,很遗憾,我恰好是做编译器的,在Facebook做了PHP编译器,在阿里巴巴领导了团队在Java里加入了透明的协程 从这一段话来看,赵海平花了很长时间问王垠的过去。 赵海平是不是可以让王垠试试解决一下自己所在团队当前遇到的技术问题,又或者让王垠试着重新实现一遍自己骄傲的“透明的协程”?这个过程,我相信是非常兴奋的。 以上两种尝试其实也算是一种试工。能解决团队遇到的问题,能做面试官能做的,应该算是能胜任他所面试的岗位了吧? 毕竟,是想招这个人来解决问题的。而不是抓住他的过去不放。 再说,有些应聘者可能真的不知道要怎么回答面试中的——真正考核的部分。所以,回答不上来,个人也觉得很正常。因为我也是那样的人。 最后,我疑问,在赵海平的这次面试里,“真正考核的部分”真的比“这个人能否真正解决问题”重要吗?HR 面,我可以理解。 后记 我们都是外人。所以,真正的背后的动机,上下文只有当事人知道。我不想评价他们个人和公司。只想讨论一下“试工”在IT行业的可能性。让更多人知道,招聘程序员,还有另一种姿势。 笔者是从这文章了解到事件的:https://www.ithome.com/0/464/417.htm 笔者的阿里三面经历:https://showme.codes/2018-06-24/alibaba-interview/

2019-12-25 · 1 min · 35 words · 翟志军 Jack Zhai

谈 DevOps 平台设计:为什么用户喜欢在构建后加一句 ls -al .

最近发现用户都喜欢构建命令最后加上一行:ls -a .。为什么呢? 是因为他们想知道执行 npm run build 后的目录的结果是什么样的。目录里到底有没有出现期望的文件。 这个功能在 Jenkins 中叫做“工作空间”。其实就是源码在 Jenkins 上下载后的目录。Jenkins 中,用户是可以直接像在查看本地文件夹一样查看这个工作空间的内容。如下图如示。 为什么用户想要看工作空间中的目录结构呢?说到底就是用户本地打包环境和平台打包环境还是有区别的。当出现构建结果不符合预期时,用户需要根据工作空间的信息来找到失败原因。 另,笔者看了行业内的几个平台,没有找到“工作空间”的功能。为什么没有这个功能呢?不知道。 后记 “工作空间”这个特性本身提高了用户在平台上的自检能力。因为平台上的信息对于用户更透明了。那么实现这个功能的成本呢?这是我们在实现前要考虑的问题。

2019-11-28 · 1 min · 18 words · 翟志军 Jack Zhai

谈 DevOps 平台设计:为什么部署后的包还是旧的包?

为什么部署后的包还是旧的包? 有位同学说他在 DevOps 平台部署后,代码还是旧的。 在我跟他确认了构建时拉取的代码是版本是对的,部署时,使用的制品包也是正确的情况下 ,我也是摸不着头脑了。 最后,这位同学在 DevOps 平台的界面上看到了部署的目标机器的IP。 这才找到了真正的原因:他们自己部署的目标机器搞错了。也就是本来想部署到 A 机器,但是部署任务填写的是 B 机器的 IP。然后自己一直在 A 机器上检查部署结果。 接着,这位同学就感叹自己对 DevOps 不熟。 然而,笔者认为,那根本不是用户对 DevOps 熟不熟的问题。而是 DevOps 平台的设计问题。 为什么用户连自己部署错了主机都不知道?笔者认为那是因为目标机器的 IP 信息在界面上不够明显,其他所有的信息就只能通过分析 DevOps 平台提供的日志才能知道了。 所以,我们的平台需要提供这两个功能: 部署清单:列出本次部署的具体内容,可以包括:制品版本,执行人,目标机器列表,部署策略,回滚策略等。 部署结果报告:制品版本,目标机器的部署结果,与上一次部署的差异(这是关键)、多次部署报告的差异性比较功能等。 部署结果报告中必须要强调此次部署与上次部署之间的差异,毕竟大多数应用不会那么频繁的更换部署机器。 后记 “DevOps” 这个概念本身已经把很多人搞得云里雾里。在网上搜索一下 DevOps 的定义就知道了。所以,用户在使用 DevOps 平台时,达不到预期值,就习惯性地认为是自己的问题。我们作为平台设计方,用户达不到预期,那就是平台设计的问题。

2019-11-27 · 1 min · 41 words · 翟志军 Jack Zhai