非专业性能测试入门

最近有接触一些性能测试的内容,斗胆总结一下,主要是想看看自己对于应用系统性能的理解,主要体现在性能测试的基础概念,测试的方式方法,还有性能问题的测试的分析策略等。

顾名思义非专业,强调纯属自己的看法,切勿别忽悠瘸了,如有不当之处,希望大家可以指正。

初识性能测试

性能测试主要就是测试一下系统在有压力访问下的表现,以便于了解系统在不同压力下的瓶颈,同时也是为了评估资源,甚至应急扩容能达到预期效果。

我记得好些年前,京东举办卖书的活动,人太多结果系统不行了,东哥说加三倍机器,结果还是被打脸了。 这个事情说明,很多时候加机器并不能解决问题,特别是没针对瓶颈来解决的话,通常是事倍工半。

说到性能测试,有几个关键指标。

  • latency,延时,表现为响应时间,就是请求-响应的时间差,越小越好。
  • throughput,表现为TPS 就是每秒完成的事务数,简单的场景可以理解为完成多少次请求,越大越好。

基本模型

如上图,我们把系统想象成一个黑盒f,在一定的并发并发用户下,持续一段时间运行最终得到一个可以接受的lantency, 还有比较高的throughput。

通常我们的目标是想了解在可接受的响应时间内,达到最高的TPS. 当然这都是在一定资源的情况下达到的, 通常来说,响应时间会随着tps上涨而增加,并到了一定程度之后,响应时间增加的比较快,而tps出现下降。

可以用一个简单的例子来类比,好比有一条高速路(系统),平时的时候,跑在路上的车多一些也没关系,一样很快(路上变化不大), 高速路使用效率高(可以通过更多车),但节假日车实在太多,虽然通过的车也很多,但就会感觉变堵变慢(路上明显多花时间), 甚至高速路变停车场,路上时间大幅度增加,通过的车反而少了。

基本模型

在压测的过程中,还有一个并发用户的概念,他是用来模拟并发用的。这里就经常有个问题,我们想要达到一个目标TPS, 需要评估用多少并发用户的问题。这里做个简单的分析,假设一次请求要100毫秒的响应时间,那么一个并发用户最多就能贡献10个tps。 如果系统远没有达到瓶颈,那么增加用户,就能有很好的效果。例如增加到10个用户,就可以达到100tps, 实际上是不能做到完全线性的, 但是有这个趋势就好了,因为会消耗很多的资源在管理上了,例如资源竞争控制,垃圾回收等等。

可能还会注意到有个时间线,通常表现为一开始比较差,慢慢的上升直到性能数据相对稳定,这个主要原因是应用没有热身, 资源没有准备好应付大流量,常见的场景有代码JIT,各种缓存的数据预热等等。后面就会表现得比较平稳。但有时候存在下降的情况,或着毛刺,有可能的原因有:

  • 数据的大量堆积导致效率下滑,常见有日志空间不足,测试数据在数据库堆太多太快影响效率(例如主要体现在统计信息陈旧)。
  • 缓存失效,例如同时失效这种情况,也会出现毛刺。
  • 有其他任务影响,例如定时触发的一些任务。

谈策略与思路

具体到了一个特定的系统或者特定的场景,就得先谈谈整体的策略思路。

了解部署架构

了解系统的部署,是我们在性能测试之前做的第一件事。 特别是解决问题的时候,如果对系统不了解,很容易就让问题描述给带偏了。 系统是一个整体,但给你的信息通常是一个局部的信息,甚至是曲解过的信息。所以要从压测客户端到系统的各个环节都画一下图, 包括经常被忽略的反向代理、内部的服务交互情况、数据库、redis、第三方接口等等。 在后续的性能测试中可以方便定界,当然如果熟悉系统架构加上调用链的支持,定界就更加容易。

认识性能基准

首先我们可以估算一个基准值,就是一个用户正常可以达到什么程度,例如10TPS,然后看能否达到增加用户TPS能增加的效果, 但TPS到顶的时候,增加资源是否可以继续增加。我们常见的错误,就是一来就对着目标性能,堆上一堆实例,行了一把过,不行继续堆。 我们还是要对变化多一些理解,例如延时怎么变化,TPS怎么变化,资源怎么变化。 另外就是要有预期,例如加用户,预计能不能提升TPS,理由是什么,实际没效果也得脑补脑补。 总之测试也是有一定目的性的,要么证明一些内容,要么否定一些内容。

确定优化方向

二八原则,根据整体的耗时占比,主要确定优先分析和优化的方向,假设固定到某一个服务,深入内部,好的方式还是日志, 如果有访问数据库,redis,业务处理的时间信息,再结合明显数据,相对容易就可以找到是调用过于频繁,还是单次过慢的问题。

评估资源

当然系统的资源都不是无限制的,一般会是cpu、内存、磁盘、网络的消耗,这需要有一个平衡。 最简单的看法,延时体现在什么,我们接到一个任务-干活-返回。其中干活就分为两个部分,真的在干活(计算),主要使用的cpu, 还有一部分是等待,表面上是怎么不消耗cpu的。而等待是普遍存在的,例如网络请求、文件读写等等,主要表现为io操作。

按照这两类资源的使用情况,通常分为io密集型,cpu密集型两类。例如我们常见的数据库,对两类资源都很高要求。一般的网站、管理系统, 属于io密集,内存数据库、缓存系统等,大多属于cpu密集。当然没有绝对的,需要根据实际情况来,优化也是朝着提高资源利用率的方向去。

基本模型

举个栗子,还是前面的100毫秒,假设有20毫秒用于cpu计算,80毫秒用于接口请求,那么无论优化程序算法,或着减少接口调用,都可以提升性能。

例如接口调用从80毫秒优化成40毫秒,明显延时就小了,TPS很容易就上去了。如果通过优化算法把CPU消耗从20毫秒变10毫秒, 看上去延时变化不大,但可以通过加大并发用户,也可以达到TPS增加的目的(可能瓶颈很快就到了接口调用那端)。

常见的资源类型

  • cpu

对CPU的查看,随着压测进展,一般有部分组件就会达到满负荷运行,吞吐量就上不去了,我们这种业务系统,通常就是把数据库打爆。 如果有数据库耗时日志,就可以排查有没有高消耗SQL。如果除去外围接口,数据库发现消耗在代码上的时间比较多,就有可能是内部的代码效率问题, 分析方式主要以火焰图、打堆栈来分析,像arthars之类的工具也有一定办法。 总体思路就是通过CPU采样的方式,看经常停留在哪些代码,这些通常就是问题。

  • 内存

内存一般多多益善的。对于java应用来说,内存过大或者过小的影响主要体现在GC上,我们主要评估GC吞吐量和单次暂停时间, 评估工具可以用jstat,例如以10秒评估一次累计10次,看gc次数、总时间、最大暂停时间等。一般的问题在于,停顿时间过长会有毛刺现象, 吞吐量太低说明gc过于频繁。通常加大内存可以一定程度解决问题,但是还是要看看有没有大数据量的操作, 例如SQL返回大量数据,优化方式例如限制处理的数据量,对耗时对象进行池化的技术等等。真的出现OOM的话,可以用一些heapdump工具来分析。

  • 网络

网络主要体现在延时上,延时一般和跨机房通讯距离有关,几毫秒到几十上百毫秒不等,如果延时过大还是很影响体验的, 可以通过简单的ping,或者发起方和接收方的时间差来判断。但是网络延时主要影响响应时间, 但不代表非常影响压测吞吐量,网络带宽我们可以简单通过可以用一个收发一个大文件来评估。

  • 磁盘

有时候磁盘I/O效率低也非常影响性能,特别是对数据库应用来说,可以通过iostat之类的工具来查看。 对于普通的业务应用来说,主要就是日志的影响了,特别是大量的日志输出要注意采取Buffer方式。

总结

初稿躺在手机里边两个星期了,还是很粗糙,不过还是发出来把。

现代的软件系统越来越复杂,功能越来越多,性能也随越来越受到人们的关注。但是性能测试绝不只是Loadrunner或者JMeter之类的工具, 更需要理论结合实践,加深对系统的理解,让性能测试学习不停留在只是工具的学习。

规则引擎从ILOG切换Drools过程总结

概述

有个项目的规则引擎一直用的ibm公司的ILOG产品,最近采用开源规则引擎drools进行替换。 下文介绍一下选型、规则文件迁移以及性能方面遇到的问题。

技术选型

成熟的规则引擎实现是比较复杂,如果直接转换成普通的代码实现,无论是转换还是后续维护的工作量都比较大,所以还是考虑采用规则引擎。

目前的规则引擎系统中,其实没有太多选择,使用较多的开源规则引擎是Drools,另外还有商用的ILOG。但这两款规则引擎设计和实现都比较复杂,学习成本高,适用于大型应用系统。

所以主要是对比一下ILOG和Drools的特性,评估可行性。

  ILOG Drools
功能特性 支持各种规则编写方式,功能丰富 类似,DRL对应规则文件,也有决策表的方式
语法规则 规则文件编写比较容易编写 DRL语法也是一种DSL,上手难度还能接受。语法基本有一对一的映射,有迁移的可行性
性能 性能高 采用Phreak算法(基于成熟RETE算法演进过来的),性能也相当不错
活跃度 活跃,发布频率也是很高的

尝试在调用入口改造,做了一些简单的功能验证,包括规则流、规则文件和决策表,都可以跑起来。 下面就是要考虑原始的规则文件怎么处理了。

规则文件迁移

存量的规则文件怎么搬,这是一个关键问题。

我们首先用手工搬了几个常规的规则文件,从中可以发现或多或少是有一些对应关系的,至少功能上应该是问题不大的。

但是项目的规则文件比较多,不同的流程,规则文件数量从几百个到两千个不等,手工转换是不现实的,要考虑程序转换。

预定义

  指定'A属性'为一个 服务属性来自(in) '服务属性列表'
  	  符合条件:如下的所有条件都成立:
  	  -当前这个A属性 的属性值 不是 ""
  	  -当前这个A属性 的属性编码 是 # "xxx"
  	  -当前这个A属性 的编码是 # "yyy";
   指定 '服务费用'  为  'A属性'取为属性双精度值;

  如果
	 'A属性' 不为空
	 并且 'A费项' 不为空
  那么
     'A费项' 初始化服务费用( 规则名称: "计算服务费" , 金额: '服务费'*100);

例如上面这个规则。很明显有“预定义-指定-如果-那么”等关键字,我们可以猜测,“预定义”表示这是一个规则,“指定”是选择原始的数据,“如果”是过滤条件,“那么”是规则要触发的逻辑。

对应到Drools规则,“指定”和“如果”都是属于条件部分(when),“那么”对应“then”。

很明显,无论是ILOG还是Drools,都是采用了一种领域特定语言(DSL),是有语法的,只是这个语法没有严格的指导说明,但是我们还是可以把它当成一种语言,解析成一个通用模型,然后再转成另外一套语言。

我们是采用Antlr这个语法解析库来解析ILOG规则(主要的g4文件连注释有600多行)。有了程序,转换工作就非常顺利了。

性能优化

最开始在环境测试,响应就几十毫秒,效果还是不错的。

后来准备上生产环境的时候,发现就慢很多,发现用的规则数差不多2千条,主要表现为:

  • 并发少量用户就不行,例如5个用户,耗时一下就上去了,几百毫秒~一两秒不等
  • 增加POD的内存,会有一定的改善,但不是很明显
  • 增加POD的数量,TPS没有明显改善,性能没法成线性增长

好吧,Drools的资料的确不多,不过应该不至于这么弱鸡的,需要分析分析。

首先,我们发现GC影响非常大(通过jstat -gcutil pid 5s查看)

S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  18.75  17.13  85.89  91.67  86.34   8713  311.998    10   27.300  339.298
  0.00  18.75  17.13  85.89  91.67  86.34   8743  312.997    12   28.400  341.397

通过火焰图也可以看到类似的情况

各种数据表明,Drools执行过程中产生大量的对象,需要大量的GC工作。

通过查阅相关资料,发现很多示例代码的写法(包括官方的代码片段)都是有问题的,在默认情况下,需要在执行规则后清理原来插入的fact对象,否则会影响存在内存的及时回收。具体资料如下:

  • https://www.cnblogs.com/daoqidelv/p/7246624.html
  • https://stackoverflow.com/questions/48533759/drools-with-high-gc-time

修复了这个bug之后,GC问题就不是很明显了,但性能依然不大行,压测的TPS还是上不去。

又翻了一波材料,发现有个sequential模式(具体不解释了),可以优化规则的执行方式,但是需要在无状态会话情况下(看不懂也请跳过)。于是改造成无会话规则执行方式,并开启了sequential模式。

KieBaseConfiguration conf = ks.newKieBaseConfiguration();
conf.setOption(SequentialOption.YES);
conf.setOption(SequentialAgendaOption.SEQUENTIAL);
KieBase kieBase = kieContainer.newKieBase(conf);

果然,调整之后,压力较少的情况下,性能有了比较明显的变化,不占用大量内存也可以跑得比较欢快,但还是并发加大的情况下,响应时间上涨比较快,加POD很难获得持续的性能提升。

为什么呢,由于规则引擎是CPU密集,如果同时处理的任务超过可用的CPU资源,那么只会增加CPU竞争,性能反而下降。于是在启动的时候,通过CPU资源调整并发线程数,多余的请求只能排队了。

// CPU密集型,需要限制线程数量,目前设置为CPU Core+1
int processors = Runtime.getRuntime().availableProcessors();
System.setProperty("server.tomcat.threads.max", String.valueOf(processors + 1));

通过这一步调整,通过增加POD可以获得比较持续的性能提升,基本满足要求。

总结

我们的同学是很优秀的,做事情也非常有耐心,没被各种没做过的事情、没见过的困难吓到。

但是适应不同的场景,需要各层面的知识,同时需要用到不同的开发工具或者分析工具。这需要在业余时间注意积累,持续学习。像各种开源软件,可定制的选项还是比较多的,需要充分阅读官方文档,遇到要多查找相关案例,通常可以找到蛛丝马迹。

在这个过程中学到很多,谢谢大家。

spring boot应用设置k8s探针的误区

最近发现有些spring boot项目在k8设置的探针存在问题,在实际运行过程中,存在突发的重启现象。借这个机会总结一下相关用法,作为后续项目参考。

k8s探针的概念

配置存活、就绪和启动探测器

上面的链接是官网的资料,可以看到三个主要的探针作用分别是:

  • kubelet 使用存活探测器来知道什么时候要重启容器。 例如,存活探测器可以捕捉到死锁(应用程序在运行,但是无法继续执行后面的步骤)。 这样的情况下重启容器有助于让应用程序在有问题的情况下更可用。
  • kubelet 使用就绪探测器可以知道容器什么时候准备好了并可以开始接受请求流量, 当一个 Pod 内的所有容器都准备好了,才能把这个 Pod 看作就绪了。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 在 Pod 还没有准备好的时候,会从 Service 的负载均衡器中被剔除的。
  • kubelet 使用启动探测器可以知道应用程序容器什么时候启动了。 如果配置了这类探测器,就可以控制容器在启动成功后再进行存活性和就绪检查, 确保这些存活、就绪探测器不会影响应用程序的启动。 这可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

探针设置的原则

我们这里主要关注就绪探针和存活探针。可看到存活探针对应用的影响非常大。

之前有不少应用是基于Spring Boot Actuator来设置探针的。例如用健康检查health这个路径来处理。

经历了生产故障之后,维护反馈要不要随意重启,会有很多问题,希望区别对待。后来在讨论中也经常提到,由人来控制什么时候重启比较好。结论就是希望提供两个路径,一个作为探针,不要检查数据库之类,一个作为监控平台的健康检查。

后来想想,health作为存活探针也的确不合适,因为:

  • 基本上health会检查依赖的中间件,检查的内容多了之后,有时候可能会容易超时。
  • 如果真的是某些依赖的中间件有问题,重启也没办法解决问题,某些情况还可能因为大面积重启造成中间件的连接风暴。
  • 很多时候,只要依赖的中间件恢复了,应用自动就恢复,不需要重启才能恢复。

所以,应用的存活探针主要关注应用自身的情况,典型的情况,例如业务线程是否正常(程序有没有hung住)。

就绪探针影响就小多了,由于它会在检测失败的时候从Service中摘除,一定程度上这是一个保护机制,让应用可能恢复正常。所以就绪探针可以敏感一些,快速隔离,快速恢复。

这样看的话,就需要至少两套检测路径,一套用于就绪探针,比较敏感,关注必要的核心组件,检测到不可用后可能触发隔离,看看是否可以自动恢复。一套用于存活探针,没那么敏感,只关注应用自身,非极端情况不触发。可能还有第三套,用于全面监控,例如部分不可用(但不影响业务)的情况也可以感知到,最敏感,内容最详细,用于监控告警,便于提前介入。

spring boot的探针支持

原本是打算定制一套,还好发现spring boot2.3已经内置了一套标准做法。无论是就绪探针,还是存活探针,都可以选择包括哪些模块的检测,非常方便。

顺手找了几个参考材料。

浅谈如何做好一名技术面试官

前两天有人找我周一给大家做个做个技术面试的赋能培训,我上公司内网找一下有没有合适的赋能材料,想一下偷懒,结果没找到,最后还是得按自己的思路来,顺便借这个机会总结一下以往的经验教训。

结合当前团队人员招聘的现状,我主要讲几个方面的事情:

  • 面试官的原则和心态
  • 岗位要求的解读
  • 技术面试的参考做法

面试官的原则和心态

首先,面试选人是非常重要的工作(如果不认同,请绕道)。作为技术团队来说,技术面试尤为重要。但目前面试过程还是比较随意的。作为面试官,希望做到:

  • 相信自己的判断,甚至这只是第一感。本来面试时间就不长,能力可能没挖掘出来,问题可能也没暴露,不苛求但要做出自己的判断。
  • 不要受招聘进度过度干扰,最终毫无底线。项目组有时候会要人要得很急,但我们不是靠堆人来做工作,要在短期掌握业务也没那么容易,加人的短期效果并不明显。另外,来面试时间也要有一定规定,约定人数,特定时间段,避免过多干扰工作。
  • 谨慎招聘低于平均水平的。什么是平均水平,主要看你周围的同事。这样才有可能让团队向上走。如果遇到水平实在太差,严重造假等情况,也要反馈,要求前头把一下关。
  • 你选人,人选你,面试你代表门面,平时要充实自己,不要被人笑话。现在的岗位分类还是比较细的, 面试官也要专业对口的,例如不要java的去面c++岗位的。
  • 不要一来就非常奇怪或偏门的问题,要循序渐进。

岗位要求的解读

我们的目标是寻找人员能力经验和岗位要求匹配度比较高的面试人员。但岗位要求,说真的,市场经济,有多少钱办多少事。但无论怎样,在团队中如果有太多小白,协作成本非常高,加人只是负作用。

所以,对岗位的要求,实际面试中,也不是完全参考的。要看面试人员的经验和岗位要求的匹配度,也要看面试人员的掌握程度,相关技能的适配程度。岗位要求分清楚有哪些是必须的,不然培养成本太高,有哪些是可选的,有就挺好,没有关系不大。人员能力中哪部分是强项,哪部分是弱项,即使和岗位要求有些差异,但是不是学习起来并不会太难?

例如我们招聘大多数技术岗位,都是要求有java的编码经验,很可能是必选的,因为我们说java通常会附带相关的框架经验,那么只有python经验可能转过来成本比较高,就不合适了。

但如果要求mybatis框架经验,面试人员没用过,但面试人员用过其他的,例如hibernete,这可能就也可以接受,但你要了解mybatis和hibernate的差异,知道关键点在哪,根据关键内容的掌握程度来判断新框架的学习成本。

技术面试的参考做法

N连问的考察方式

这种方式在网上也比较常见,就是针对同一个知识点,多提几个问题来考察应聘者对知识和技能的掌握水平

比如对方的简历上写着熟悉多线程,你就可以这样来提问。

1)你了解多线程吗?

对方可能会回答:“了解”、“熟悉”、“用过”。你可以接着问。

2)你们多线程用在什么场景,用到库之类?

对方可能巴拉巴拉说一堆。对方可能会提到线程池,你接着问。

3)JDK自带的线程池机制是怎样的?

那么还可以接着问。

4)JDK自带的线程池默认带了哪些实现?

对方可能能举出有哪些实现,每个实现有哪些缺点之类。那你还可以继续。

5)怎么评估线程池大小,能不能动态调整池的大小?

这个可能就比较麻烦了,对方可能能答上一些,那你还可以在操作系统机制,实现方案上继续讨论。

项目经验描述+引导

不得不说,很多面试人员,简历写的很不好,再加上自己介绍也比较简单的。

我们可以先让面试人员介绍一下自己熟悉的项目,有什么重要的业务流程。这个业务流程采用什么技术实现的。

对方可能会说一下业务流程是怎样的。(我们主要关心有什么比较典型的业务场景,和技术方案),用的什么框架,用了什么中间件,大体是怎样的巴拉巴拉。

你可以问问为什么这么做,有没有其他方案。

也可以问问各个组件是怎么通信的,数据结构是怎样的,巴拉巴拉..

当然,你关心或感兴趣的地方,可以用N连问的方式挖掘一下。这个过程主要是感受一下面试人员的分析、理解的能力如何,沟通能力如何,能不能把事情讲清楚

“走马观花”找亮点

这个主要是面试之前做的,拿到简历之后,浏览简历看看待会问什么问题,同时看看有什么有趣的、不同的内容,提前准备

我一般会关注一下:

  • 工作经验怎样,工作经验长的会根据情况提高期望,工作经验少的多关注基础、学习能力。
  • 知识面怎样,到时候可以多关注会什么,而不是不会什么。例如一般前端,那么会点后端就是加分项,当然主要关注点还是前端能力。
  • 有没有总结分享的习惯,例如有没有博客、开源项目之类,有时间的话我会上去看看。
  • 有没有学习的习惯,例如有时候会问问最近学什么,看什么书,当然也要求讲讲具体内容是什么。
  • 学历怎样,行业经验怎样,有什么竞赛经验之类(或多或少会有第一印象,但我们要尽量避免定型)。

白板面试

主要针对开发人员的,也经常使用,都是一些算法题。虽然很多人抗拒这个,但在难度适中的情况下,我还是比较乐意推荐的。一般的初中级开发人员,我选择的问题:

  • 不用一些特别的算法,例如动态规划之类
  • 代码长度不长,在20行左右的核心逻辑
  • 避免技巧性过高、过于数学化的情况
  • 需要顺便回答一点算法时间/空间复杂度判断或优化

总结

从团队的角度,每个公司每个团队都有自己的风格,所以招聘风格也是有所差异的,有些精益求精,有些大包大揽,有些深挖底层,有些硬钢算法。

从个人的角度,我个人虽然参加过很多次面试,但回想下做得也并不是很好,能趁此机会总结一下也好。我发现,很多时候前面一两分钟的感觉很大程度就决定后面要不要,基本上问问题也有一部分是在照顾对方情绪而已。

所以很多东西无所谓好坏,形成自己的风格和判断最重要。

对检查列表的一点看法

什么是检查列表(checklist)?

我们一个项目告一段落之后,通常会有一些知识沉淀。这些沉淀的意义在于同类型项目具备哪些指导意义,在后续做同类型工作的时候,提前发现一些问题。

其中有一个常见的措施就是检查列表(checklist),对着列表一项项,不容易遗漏重要问题,可以及时排查隐患。

检查列表有什么标准?

在最近的xx化项目里面,检查列表同样也是很有必要的。首先它是一系列项目工程的改造,具备一定的共性,另外大家普遍对相关技术比较陌生,工作开展很容易只依赖某些人的经验。

我们检查了对应项目的检查列表,发现实际的指导意义不高。简单的说,就是看了也没什么用,不知怎么下手。

后来我们意识到这其实是一个普遍现象。

我们认为检查列表的核心是可操作性。这和规范的作用是有些差异的,规范是说我为什么要做这个,不做这个会有什么问题,什么才是正确的做法。但在实操过程中,我需要理解,这个东西我怎么去检查,检查标准,检查步骤是不是明确的。还有更进一步的是,检查列表也要适当关注检查效率,检查步骤是否工具化,还是说只能单靠人力。

让我们想想,假设我是一个新人,当我拿到检查列表的时候,对我的知识背景有什么要求,能不能帮助我开展工作,我按照这个检查列表去操作的时候,结果是不是可信的?

检查列表何去何从?

图例1

一般的情况是这样的。

我们会遇到各种各样的问题,在解决问题的过程中,逐渐发现某些问题存在共性,我们把这部分问题以规范、设计准则的方式固化下来,作为后续开展同类型工作的标准。但规范可能是比较详细的,方方面面都照顾了一下,在实际操作中不容易抓住重点,容易遗漏。我们再对规范中的要点进行提取,针对步骤、结果进行实例化,甚至进一步提炼检查工具,形成检查列表,希望可以更多更快的提前发现问题。

按照这个先后顺序,肯定是已经遇过问题,并且有意识的总结过。实际也是有的,只是存在某个人的脑子里边。如何形成知识管理,靠自觉是不大行的,主要靠督促,我的做法比较暴力,我看到某同学在处理某个问题,有思路解决之后,我会要求把输出成文档总结,对配合性比较好的同学,我还会对内容有更多要求。输出之后,再广而告之。

我们可以看到,一些特定领域的规范,已经可以直接跳过检查列表,完全的工具化。例如代码静态检查的findbugs、checkstyle之类,例如阿里的java规范,也可以通过pmd形成工具落地。例如安全相关的规范,也有一些检查工具。但大多数的场景,还是没有办法工具化的,或者部分工具化,我们更专注的是,如何才能更容易操作。

例如,我们发现更换环境可能存在网络放通问题。那检查列表可能就有一项检查网络放通,但要点肯定是知道有哪些地址需要放通。的确,这不直观,怎么提升可操作性呢? 可以先从单纯的思路开始,我们可以说,收集各个外围平台(从设计、测试、运维的角度来收集)。也可以说,根据代码中的相关代码来分析(例如网络访问的api等关键字),反推访问的地址。其中第二点是可能实例化的。虽然没法工具化,但这样是不是更好一点?