精准测试是个错误

如果你已经了解了精准测试在行业的主流做法,你可以跳过相关内容。 行业里对于精准测试的定义 在网上流传着一些精准测试的定义(如果你对这些定义不感冒,可直接跳到我个人的定义): 自网易陈逸青(2020)的定义: 借助一定的技术手段、通过辅助算法对传统软件测试过程进行可视化、分析及优化的过程,使得测试过程更加可视化、智能、可信和精准。 原文:https://www.infoq.cn/article/xuu91crqa4hcjz8uomjs 来自HSBC的测试咨询专家齐磊(2021年): 通俗点讲:核心基于源代码变更分析,结合分析算法,确定影响范围,提升测试效率。 原文:https://www.infoq.cn/article/2feiv8a5kogaqlbzwosh 来自星云测试(2022年): 精准测试一句话概括就是:测试用例和代码之间的追溯,这是它最本质的东西。精准测试的本质决定了它抓住了测试的一个核心要点。 原文: https://testerhome.com/topics/34557 来自得物技术(2023年): 精准测试是基于源代码变更分析,结合一些分析算法,从而确定改动代码影响的范围,设计测试用例进行针对性测试,一方面可以提升测试效率,另一方面精准测试还可以将测试用例与程序代码之间的逻辑映射关系建立起来, 而这个过程则是通过工具去采集测试过程执行的代码逻辑及测试数据。这两个点也正是精准测试的核心:正向追溯和逆向追溯。原文: https://tech.dewu.com/article?id=43 以下是来自网易严选的架构图: ![](/assets/images/网易严选的架构图1.png]] 我个人的定义 在笔者看来,精准测试的定义应该是这样的:它是一种能力,能只针对变更进行测试,而不是每次变更都进行全量测试。注意,我指的是“变更”,而不只是“代码变更”,也就是说所有类型的变更,包括手动变更。 精准测试的思路并不复杂,分成三个步骤: 找到变更; 根据变更找到相关联的测试用例; 只执行相关联的测试用例。 其实,把这种方法叫增量测试(Incremental Testing) 更准确,更合适。毕竟你是针对增量的代码变更进行测试。 如果不是针对增量变更进行测试,你也能只执行一个你想测试的测试。难道这样不算精准测试吗? 国内行业主流的实现精准测试的方法 步骤一:找到代码变更 通过commit之间进行差异对比​。​ 步骤二:根据代码变更找到相关联的测试用例 要做到“根据代码变更找到相关联的测试用例”,我们就必须知道代码与测试用例之间的关系。 获取这个关系的做法是在执行测试的同时,做以下事情: 将流量记录下来; 将因流量而执行地代码的调用链记录下来; 将测试用例的元数据与代码调用链的关系记录下来; 这个过程就完成了对被调用代码与测试用例之间的映射关系的建立。 另,现实往往存在很多未被测试用例覆盖到的代码,这时,通过静态代码分析和测试覆盖率计算技术结合,生成未被测试到的代码的报告。 可以看出,通过以上方式“找出代码与测试用例之间的关系”的成本是极高的。所以,在这个领域会有:引流平台、测试用例管理平台、精准测试平台等等平台。这也给大家一个感觉,我们要先有一个平台才能做到精准测试。 说到底就是通过插桩技术,构建代码的执行路径,并找到​对应的测试用例之间关系。 目前在网上目前看到大多还只是针对Java语言或者C++来实现精准测试,其它的语言目前没有见到。 步骤三:只执行相关联的测试用例 当有了代码与测试用例之间的关系,只执行相关联的测试用例就简单很多了。 主流方法的坑 以下是齐磊总结的精准测试存在的问题: 基于手工测试的精准测试建立映射关系繁杂,如果需求改变频繁,用例维护以及之间的关系维护需要耗费大量时间精力。 精准测试需要一定的自动化测试的覆盖,这样做起来更有意义,例如 api 自动化测试,如果本身用例过少,与代码之间关联关系不多时,变更代码后可能不会得出什么结果。 最好有对应的用例管理系统,能够方便的帮助我们建立与代码之间的关系。 需要投入开发能力强的 QA 或者测试开发建立整套系统环境,但长远考虑,将精准测试嵌入整个公司的质量平台中,不管对于新项目还说维护项目来说都是一种提升。 项目生命周期需要较长,短期项目花费巨大精力开发和维护整套精准测试系统得不偿失。短期项目可以利用精准测试以 api 测试覆盖率作为衡量标准。不去建立繁杂的关系,只监控 UI API 测试覆盖率迭代时的变更来达到目的。 但是,个人认为齐磊总结的内容没有问题,的确都是坑。但是那些不是精准测试的坑,而是国内行业主流的实现方式的坑。直白地说就是喝水时,喝水的角度错了。 为什么主流实现方法从方向上就是错的 为什么我认为以上地坑是由实现方法导致的?以下是我的论点,欢迎讨论指正: 该方法只局限于单一语言 准确来说,精准测试不应该只针对代码的变更,而是所有的变更。更不应该只针对单一语言的变更,而是可以针对所有的语言。 因为精准测试的定义本身不局限于某种语言的代码变更,而是对一个软件工程中所有的变更而言。一次SQL的变更,你是否需要精准的知道要执行哪些测试?一个前端的CSS代码的变更,你是否需要精准的知道要执行哪些测试? 目前行业里主流的方法,只是针对单一语言下的场景而设计的。按同样的思路是无法做到多语言的。我说的多语言指提同一工程下的多语言,不是指相互独立的单语言工程。 只能在平台上做精准测试 即,我们首先需要一个平台,才能做到精准测试。 但我们希望在开发者本地开发环境就可以做到精准测试。 最后 文章标题并不是说“精准测试”本身是一个错误,是想说上述的实现方法是一个错误方法。 ...

2023-04-21 · 1 min · 74 words · 翟志军 Jack Zhai

当同事实践Everything as Code之后

背景 团队基于Jsonnet(配置语言)和Bazel(构建工具)实现Everything as Code。但是,将近一年的时间里,团队也只有少数人深入参与Everything as Code的代码的编写(其实,大多数人是不需要深入参与)。 最近,组内的一个开发同学——他之前对Everything as Code完全零基础——在运维同事的辅助下,为网关配置增加了金丝雀的能力。 在这种能力下,开发人员可以只需要改几行配置,并部署配置,就可以实现金丝雀发布。这种能力的根本就是:通过Jsonnet动态生成网关“根据Header进行流量路由”的配置的能力。 如果没有这种能力,需要手写大量的重复的YAML配置,即麻烦,又容易出错。 同事使用Everything as Code的工具后有感 在他与Everything as Code“亲密”接触一个多月后,他说出了他的感受: 直接写yaml的话,所见即所得,非常直观。但是有个致命缺陷,没法动态化生成配置,所以必须要寻找一个脚本语言。 jsonnet其实就是一门简单化的脚本语言,通过自定义方法,通过for循环,通过读取自定义的变量,更灵活生成我们想要的json。但是写代码都有一个共性,代码可以写的很复杂,现在用jsonnet了,你想看一个key的value是什么,需要看懂别人的代码才知道value是什么甚至可能理解错别人的代码,违背了配置所见即所得,这对新手来说非常痛苦。很多时候,我们不关心jsonnet的过程,我们只想看到生成最终的配置文件是什么。 如果能把云端编译好的jsonnet展示出来,就可以看到生成的最终json是啥了,但是我们没有。所以需要本地搭建bazel,但是bazel对win非常不友好,搞起来非常困难,但是本地如果不能把monorepo buil通过,那么可以宣告你无法彻底搞清楚monorepo,更不可能自定义更多自己想要的东西了。 既然是通过代码来生成json,用jsonnet和python和js甚至是用java都可以,现在我觉得jsonnet的设计者对灵活性做了一个取舍,有一些我想要的操作jsonnet没法实现。 然后他又补充到: 只要自己本地能build monorepo,那么就既能享受jsonnet的灵活性,又能通过编译好的文件做到所见即所得。可惜bazel对win不友好,新手能在win 编译通过mainrepo太难了。 总结下来,这位同事: 对Jsonnet的理解还不够:Jsonnet并不是脚本语言,而是一门可编程的配置语言,一种为配置而生的DSL(领域特定语言); 在Windows系统上使用Bazel遇到了非常大的阻力。 以上是同事针对Jsonnet和构建工具Bazel的感受。 我认为不是Bazel对Windows不友好,而是Bazel在Windows下的生态太弱了。谁叫后端服务是Linux的天下呢? 同事对Everything as Code本身的看法 接着,他说出对Everything as Code的看法: 我觉得everything as code太理想,只能面向开发人员。你不能保证运维的能力,绝对不开放给第三方使用。指不定某天某个需求就需要你的运维的某个能力,让不懂代码的人也要操作。 假如某个运维能力,要开放给产品或者测试来用,要让别人给你学个jsonnet,那要我是产品或者测试只能口吐芬芳了。所以我认为,面向开发者的部分,使用every thing as code是趋势,比较好溯源跟踪,迭代。但是架构设计上,还需要有支持面向第三方的部分,可以做到让不懂代码的人也能用到一些运维的能力。 这位同事实现的是金丝雀配置生成,是需要修改Jsonnet代码的。当产品经理需要将某用户的流量路由到后端服务的某个版本上时,这位同事就认为产品经理就需要去改Jsonnet代码了。 同事认为这就是Everything as Code的问题:不方便非开发人使用。 同事的另一层意思没有说出来:并不是所有的事情都适合as Code。 其实,有这样的误解很正常,“Everything as Code”中的“Everything”字面含义上就是所有的,一切的意思。而Code是代码的意思。 所以,“Everything as Code”字面上完整的意思是:一切皆代码。 从字面上理解“Everything as Code”,只看到了它的表面 Everything as Code的本质 “Everything as Code”中的”Code“,其实指的是配置,即:一切皆配置。 这句话本身是没有错的,如同“道生一,一生二,二生三,三生万物“这句话。 “Everything as Code”这句话并没说什么是配置,以及哪些配置该放哪。这才是我们实践时真正要考虑的问题。 配置的本质是软件的灵活(soft)部分。通过这个”灵活部分“,我们可以根据自己的需求,有限地改变软件的行为。 ...

2023-04-20 · 1 min · 83 words · 翟志军 Jack Zhai

基于Bazel + SQLFluff实现SQL lint

背景 SQL进行版本化控制后,我们希望为SQL加入lint步骤。这样做的好处是我们可以在真正执行SQL前发现问题。 本文中,我们通过Bazel执行SQLFluff以实现SQL的lint。 SQLFluff是一款使用Python语言使用的,支持SQL多方言的SQL lint工具。 它的特点是: 支持多方言。如:Snowflake、PostgreSQL、ClickHouse。所有支持的方言列表:https://docs.sqlfluff.com/en/stable/dialects.html; 可以输出正确的SQL,减少了我们手工修正SQL的工作; 同时支持命令行方式使用和API调用方式。 集成到CI/CD流水线中 在我看来,在CICD流水线中实现SQL lint有两种方式: 方式一:在流水线中增加一个SQL lint步骤; 方式二:将SQL lint的逻辑写在测试代码,执行测试步骤,就自动执行了SQL lint。 方式二是我最爱,我会在本文最后讲原因。 工程结构 . ├── BUILD.bazel ├── WORKSPACE ├── repository-hibernate-impl │ ├── BUILD.bazel │ └── src │ ├── main │ │ └── sql │ │ └── V1__runbook_table.sql │ └── test │ └── python │ ├── BUILD.bazel │ ├── requirements_lock.txt │ └── sql_test.py 步骤1: 在WORKSPACE中增加Python外部依赖 本文中我们使用的是Bazel 5.4.0,所以还在使用WORKSPACE定义外部依赖 http_archive( name = "rules_python", sha256 = "a644da969b6824cc87f8fe7b18101a8a6c57da5db39caa6566ec6109f37d2141", strip_prefix = "rules_python-0.20.0", url = "https://github.com/bazelbuild/rules_python/releases/download/0.20.0/rules_python-0.20.0.tar.gz", ) load("@rules_python//python:repositories.bzl", "py_repositories") py_repositories() load("@rules_python//python:repositories.bzl", "python_register_toolchains") python_register_toolchains( name = "python3_11", python_version = "3.11", ) load("@python3_11//:defs.bzl", interpreter_3_11 = "interpreter") load("@rules_python//python:pip.bzl", "pip_parse") # Create a central repo that knows about the dependencies needed from # requirements_lock.txt. pip_parse( name = "pip_deps", python_interpreter_target = interpreter_3_11, requirements_lock = "//repository-hibernate-impl/src/test/python:requirements_lock.txt", ) # Load the starlark macro which will define your dependencies. load("@pip_deps//:requirements.bzl", "install_deps") # Call it to define repos for your requirements. install_deps() 步骤2: 定义SQLFluff依赖 requirements_lock.txt的内容如下: ...

2023-04-17 · 2 min · 315 words · 翟志军 Jack Zhai

和行业里多家DevOps平台的同学交流后,我发现……

前段时间和不同的人交流了DevOps平台后,大概了解了行业里DevOps平台是怎么回事。 DevOps平台最大的问题 DevOps的定义是什么?面对这样的问题,我想说行业里,10个人可能有11个答案。既然DevOps的定义在行业都没有一个权威的定义,那么,对于DevOps平台是什么这样一一个问题,自然也就没有权威的定义了。这就是行业里DevOps平台最大的问题。 P.S. 对于DevOps Master证书又应该如何定义呢? 如果DevOps平台没有定义,那么,我们就无法以下类似的问题: 它解决了谁的什么问题? 行业里,它的趋势是什么? DevOps平台发展到后期,是不是AIOps? 因为,你再怎么回答这些问题,只要你与提问人对于DevOps的认知不一样,你都会与提问人内心的答案不一样。 这让我想起马斯克的名言:我现在不和人争吵了,因为我开始意识到,每个人只能在他的认知水准基础上去思考,以后有人告诉我2+2等于10,我会说,你真厉害! 谈DevOps平台的设计 我看到的是它们有很多功能:项目管理、需求管理、测试管理、流水线、制品管理、自动化部署……所有人都类似地美其名为:一站式研发云平台。 可是,当你在使用时,你会发现,它们不过是在以前的项目管理平台、测试管理平台、流水线平台、制品管理平台、部署平台等多个平台的功能的重新堆砌。而这些功能之间有有联系吗?很少。 行业里不少客户会要求DevOps平台的Dashboard,不同的角色进入要显示不一样的东西。其实就是开发者进入Dashboard应该只显示开发者关心的功能,测试人员进入Dashboard应该只显示测试用例相关的功能……这是不是可以成为康威推论的一个佐证? 总的一句,DevOps平台不过是过去多个不相关的烟囱系统,通过一个Dashboard,让它们显得像是一个平台。 研发效率有最优解吗? 和这么多人交流后,发现大家还是有一些共识的。那就是:DevOps平台应该是可以提高研发(or 运维)效率的(如果我只说研发效率,估计有人会以为我认为DevOps平台只是为研发侧服务的)。 行业里,To C产品的设计,最优解通常是未知的,是需要不断寻找的。所以,发展出各种方法论寻找方法论。这对于To C产品的设计是有效的。因为它的前提是最优解真的在于用户。 抛开产品设计方法论,对于研发效率的提升这个领域, DevOps平台的设计者应该比用户知道最优解是什么? 那我们使用To B的产品设计方法论去设计如何?个人觉得,即对,也不对。对的地方是DevOps产品毕竟是卖给企业的,所以,在设计DevOps时不得不考虑谁给它买单这个问题。不对的还是我上文提的最优解问题。 DevOps平台与Srcum、敏捷、迭代开发之间的关系 如果你的DevOps平台不与这些听起来牛x、高大上的名词关系起来,在这个行业里,你的产品估计有点难打开市场。 这就要求,我们在设计DevOps平台时,不得不考虑行业里的人对于Scrum、敏捷、迭代开发的理解。 个人觉得难点在于:在DevOps平台的设计上,无论用户希望使用何种方法论,都能在平台内实现DevOps平台本身的目标,同时平台还能保持自身的简洁。 用户使用那些方法论背后的目的才是关键。 后记 感谢这些同学花时间与我交流。本文作为一篇交流文章,目的不是为了贬低DevOps平台。

2020-11-02 · 1 min · 34 words · 翟志军 Jack Zhai

持续构建、持续测试、持续集成、持续部署、持续交付、持续.....“持续”到底是什么意思?

虽然,读者朋友可能觉得自己已经理解这些概念了,但是,还是希望读者读完。笔者从权威的书上将这些概念的定义摘抄下来,最后给出笔者对于“持续”的理解。 构建(Build): 一次构建不止是一次编译(或者动态语言中的某种称谓)。一次构建可能包含编译、测试、审查和部署以及其他一些事情。一次构建是将源代码放在一起,并验证软件可以作为一个一致的单元运行的过程。摘自《持续集成》 其实构建过程中还可以包括测试、部署。这点可能和很多人的理解有出入。这里就会有疑问了,既然构建中包括了部署,那么持续构建与持续部署又有什么关系?笔者是这样理解的,因为软件系统是需要部署了,才能测试的,所以,为了在构建过程加入测试,就必须引入部署。 部署(Deployment): 部署是一种技术领域的操作,也就是说从某处获取软件包,并按照预先设计的方案将其安装在计算节点上,并确保系统可以正常启动,但它并不定意味着“必须包含业务功能的发布或交付”。摘自《持续交付2.0》 交付(Delivery,也被称为发布): 是一个业务决策活动,通常也被称为“发布”,也就是说,如果将新的构建的特性交到客户(用户)手中,用户就可以看到并使用它们。摘自《持续交付2.0》 我们可以将代码部署上生产环境,但是我们可以通过某种技术手段,让用户看不到,也不能使用它。这就是只部署,但不交付。部署与交付的差异在于部署是技术端操作、交付是业务端决策。 这里,读者可能又有疑问了:未完成的功能,可以部署上生产环境吗?笔者的回答:是的。前提是你能控制该功能是否对用户可见。这称为功能开关。 持续集成(CI): 它是一种软件开发实践,即团队的成员经常集成他们的工作。通常每个成员每天至少集成一次——这导致每天发生多次集成。每次集成都通过自动化的构建(包括测试)来验证,从而尽快地检测出集成错误。摘自《持续集成——软件质量改进和风险降低之道》 注意,持续集成中包括了构建与测试。所以,我们在行业里经常听到的“持续测试(CT)”又是什么呢?这是笔者的疑问。 持续交付1.0(CD1.0): 持续交付是一种能力,也就是说,能够以持续方式,安全快速地把代码变更(包括特性、配置、缺陷和试验)部署到生产环境上,让用户使用。摘自《持续交付2.0——业务引领的DevOps精要》 持续交付2.0(CD2.0): “持续交付2.0”建立在“持续交付1.0”的“可持续地快速发布软件服务”及精益创业的“最小化可行产品”两种理念基础之上,强调要以业务为导向,从一开始就业务问题进行分解,并通过不断的科学探索与快速验证,减少浪费的同时,快速找到正确的业务前进方向,简称为“双环模型”。摘自《持续交付2.0》 持续集成、持续部署、持续交付之间是什么关系呢?笔者认为是:持续交付的过程会包含持续部署,持续部署的前提是持续集成。把集成与部署组合到一起,并完全自动化,这个自动化的过程,称为部署流水线。持续交付1.0强调的是交付的效率,持续交付2.0则除了强调交付的效率,还强调交付的效果。 最后,我们来谈谈“持续”,笔者是这样理解的: 所谓的“持续”,就是指经常地做。而“经常”是一个相对的概念。对于每年交付一次的软件系统,优化成每个月一次,也算是“持续”了。另,“持续”代表的是一种能力。有能力持续交付,但是业务不一定允许。要实现“持续”的能力,自动化就成为了必然的选择。 说到了“持续”就不得不说“持续改进”。上文说过,持续指的是经常做。持续改进的意思是经常做改进。持续改进的极限是無時不刻地在改进。那么,如何让一个团队无时不刻地进行改进呢?这是一个非常大的话题。关注笔者的公众号,将来会讲到。

2020-09-16 · 1 min · 21 words · 翟志军 Jack Zhai

一些持续交付的实践经验

分析团队的问题 我是2020年3月份加入该部门。刚加入时发现问题还挺多。而这些问题在行业里都很典型,比如: 分支管理不统一:虽说大部分人还是在master上开发,但是还有部分人自己拉feature分支开发。 没有统一的制品打包:Docker镜像的打包基本都是在开发人员的电脑上进行的。 对制品仓库的push权限没有管理:每个人都有push权限,而且使用的是同一个账号。 没有版本管理:在交给测试人员测试(俗称提测)时,开发在本地打包后,push上制品库的包的版本号为uat20200302(UAT是测试环境的简称)。测试通过后,再使用此版本号,部署到生产环境。结果就是你会看到生产环境运行的包的版本:uat20200302,是不是很奇怪? 没有监控:这也是很多团队的通病了。 没有单元测试:开发人员有在main方法写单元测试的,有写出来的测试是无法自动化的。 开发团队没有自己的自动化测试。 多个应用部署在同一台机器。 手工部署:每次部署都是人工登录到服务器执行部署。 数据库没有版本化。 没有代码审查。 问题还有很多,就不一一列举。在笔者看来以上问题的最终表现都是软件系统的质量低下。笔者希望通过实践持续交付以提升软件系统的质量。 但是问题是该如何实践呢?笔者认为只要掌握了它的基本原则,剩下的就是根据实际情况结合基本原则来解决问题了。 持续交付的原则 幸福的家庭都是相似的,不幸的家庭各有各的不幸——《安娜卡列尼娜》 从《持续交付》书中,基本原则有: 为软件的发布创建一个可重复且可靠的过程 将几乎所有的事情自动化 把所有的东西都纳入版本控制 提前并频繁地做让你感到痛苦的事 内建质量 “DONE”意味着“已发布” 交付过程是每个成员的责任 持续改进 我们可以这么理解这些原则:基于所有东西都要进行版本化的原则,所有的东西都要代码化。 因为代码化以后就可以放到类似Git这类版本化工具中。而代码化以后的东西就可以很容易地实现自动化。在实现自动化以后就可以为软件的发布创建一个可重复且可靠的过程。 实现自动化的过程是需要每一位成员持续参与的,因为交付过程是每个人责任。 “DONE意味着已发布”是团队每个成员都要达成的共识。达成共识后,才能更好的参与持续改进。在持续改进过程中,我们的软件系统就获得了内建质量。 笔者认为,在持续交付中,代码化与版本化是基础。 实践持续交付 在理解原则后,我们就可以开始实践了。可是该如何下手呢?笔者通常遵循以下指导思想: 先CI,后CD。 无监控,无安心觉。 先配置项版本化,后标准化,最后才有自动化。 根据指导思想,再结合团队的实际情况,笔者做出以下计划: 打包自动化。 实现基础监控(机器级别监控、中间件监控)。 实现所有的配置版本化。 实现自动化部署应用。 实现应用监控。 实现数据库版本化。 实现业务监控。 研发数据收集 …. 由于团队原来已经有日志收集机制,所以,暂且不需要实现。以上步骤只代表一个优先级。如果团队人力充足,可以同时一起做。 虽说有了计划,但是团队不具备相应的能力,什么计划都白搭。 1. 打包自动化 之所以使用“打包”这个听起来不怎么“高端”的词,而不是使用“构建”。是因为“构建”这个词,太容易引起歧义。而且打包这个词很形象,就是把源代码编译后,链接,最后打包成一个可执行包。当然不同的编程语言,打包过程可能不同。 因为大多数团队都没有写自动化测试的习惯(我们团队也不例外),让他们写自动化测试,他们只会觉得自己的工作量增加了。所以,我在团队中导入持续交付实践时,一开始就不要求自动化测试。团队意识的转变需要很长的过程。这是使用“打包”的第二个原因:它不包括自动化测试。 要实现自动化打包,其实并不难。基本步骤就是: 搭建制品库:Nexus。 搭建自动化服务:Jenkins。 在Jenkins中创建pipeline任务。 在业务代码仓库中加入Jenkinsfile,将打包逻辑写到Jenkinsfile中。 所谓打包逻辑就是你在本地开发时,利用IDE或命令将源代码编译成可执行文件的过程。打包自动化的过程,就是将你在本地执行的打包过程“搬”到自动化系统上执行,再加上一些优化。 在这个阶段中,我们需要实现: 统一制品库:收回所有人上传制品的账号。只能由Jenkins打包上传。 统一版本号:比如使用格式年-月-日-commitId-构建号来定义所有的后端应用。注意,不管使用哪种方式,你必须很容易的根据版本号找回相应的源码。 统一分支管理:使用主干开发,分支发布的模式。我们根据团队情况有稍微做了一些改变。发布并没有切分支出来,而在发布后发现某版本有Bug,我们就会从该版本的代码切一个分支出来改,打包,部署。最后再将该分支的commit cherry pick回master分支。 2. 实现基础监控 没有监控,在我们这个行业太常见了。所以,在我加入团队后,发现几乎没有任何监控,也就没有什么好惊讶的了。所以,在解决打包问题之后 ,紧接着就是给所有的机器加上监控。至少机器的CPU、硬盘、内存等要监控起来。 上一阶段,我们已经把Jenkins搭建起来,所以,Prometheus就开始自动化部署了。 使用Prometheus的原因很多,但是关键是它的配置是代码化的,非常容易版本化。持续交付的原则:将几乎所有的事情自动化、把所有的东西都纳入版本控制。像Zabbix,使用需要使用界面进行操作的,就被我排除了。 ...

2020-09-09 · 2 min · 249 words · 翟志军 Jack Zhai

工程化实践:使用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