2021年马上就过去了,去年这个时候我写了一篇2020年FunTester自我总结,感觉也是对FunTester有个交代。
2021年也不能例外,下面分享一下FunTester在2021年末的自我总结。
公众号
2021年FunTester的重点还是在公众号上,目前已经730+原创文章,7200+的粉丝,算是一个里程碑。今年彻底放下了去年的 日更 flag,自然也少了很多非更不可的压力。精神上轻松了许多,自然文章的质量上也有所提高。不少同行问我为何有那么多东西可写,古语有云:问渠那得清如许,为有源头活水来。文章主要分三类:一类是是我工作中遇到的问题,想到的解决方案;一类是我自己的学习实践,一类是一些非技术类的感悟和读书笔记。
2021年FunTester公众号多了几位作者,有的是粉丝,有的是自媒体同行,通过授权搬运和转载的形式丰富了FunTester公众号的内容:
社区风采
- Linux文件系统和vim命令
- Linux/Mac简单又强大的基础工具(一)
- 《漫画算法》读书心得(一)
- Jmeter基于webscoket测试后台服务接口实战
- 初遇Postman,SayHi的三种方式
- Airtest-android快速入门与实战
- 安卓APP测试知识大全【面试储备】
- 颇具年代感的《JMeter中文操作手册》
- Postman进阶
- Java正则学习笔记
- 大厂三面都问什么
- 腾讯子公司三轮面试经历
FunTester测试框架
FunTester测试框架今年主要在性能上和压测模型两个方面进行了拓展。性能上基本达到了目前主流压测工具的一流水平。满足了目前所有的单机压测需求,单机支持了10万QPS以上。主要的资源占用也做了一些优化,大部分是在数据收集和计算以及在压测过程中的各种标记收集功能。
有文为证:
分布式
当然如果单机性能也有瓶颈,那就必需祭出分布式这个大杀器。在参考了ngrinder分布式测试框架的设计思路之后,我写了FunTester分布式框架设计初稿。
有文为证:
关于分布式用例设计的话,我使用了三种用例模式:固定模型、内置模型和脚本模型。分别对应三种用例执行思路:
- 组装用例对象,使用FunTester框架模型,然后执行;
- 使用内置的用例,通过参数化之后反射执行;
- 使用Groovyscriptengine直接执行脚本。
有文为证:
- 分布式性能测试框架用例方案设想(一)
- 基于docker的分布式性能测试框架功能验证(一)
- 分布式性能测试框架用例方案设想(二)
- 基于docker的分布式性能测试框架功能验证(二)
- 分布式性能测试框架用例方案设想(三)
- 基于docker的分布式性能测试框架功能验证(三)
压测模型
动态模型
关于已经存在的压测模型下半年拓展了一些新功能,目标的方向就是动态模型,目前已经完成了功能性的开发,还需要在测试中实践和优化。还有一个中间态的压测暂停的模型,就是在不断增压过程中通过接收外部信息触发压力暂停。有文为证:动态模型之增压暂停【FunTester测试框架】。还有一种终极版本可以在压测过程中随时增加和减少压力动态模型之动态增减【FunTester测试框架】,这样我们压测中,就可以随心所欲控制发压的线程数来控制压力值。基本上做到一次测压多个场景的验证,省去了每次执行压力都需要递增等待的时间。
未来另外一个方向就是动态注入压力,除了程序启动时自定义好的压力模型之外,还可以动态注入新的压力模型。条件压测流量的构成比例,以适配更多场景的一次性压测验证。
重写QPS模型
之前的QPS压力模型,主要思路是通过控制向线程池丢请求任务的线程数和等待间隔来控制QPS,这种模型存在一些问题:1.必需新建额外线程;2.自实现的sleep功能缺少精度和稳定性。目前已经转向goreplay的方法实现,通过定时器来控制QPS递增,但是Java中使用定时器又会带来较多的线程开销。后来会结合日志回放中的实践结果来进行优化。
日志回放
我之前是不怎么喜欢回放这个功能的,但是在使用了一段时间的基于goreplay开发的压测平台后,逐渐意识到自己的不足。后面有了个契机,学了了Go语言,开始阅读goreplay的源码,在感叹设计精巧的同时,也发动了拿来吧你抄能力据为己用。其中channel的设计是我先学到的,目前在Java框架中使用了Disruptor高性能消息队列进行了功能演示。
测试效果还是很不错的了,千万级的日志回放场景,单机QPS达到了8.8万,逼近物理极限,我已经很满足了。
编程语言
Go
2021年最大的进步还是学习了新语言Go。虽然过程依然坎坷,总算是熬过了最难熬的阶段,现在基本看懂研发代码逻辑和进行简单改造已经没有问题了。其中一位大佬指点:learning by doing,让我受益匪浅。在这个学习过程中也产出了不少的文章,大致的路径就是把现在Java完成的功能,重新使用Go语言写一遍,工程量宏大,目前HTTP、WebSocket已经完事儿了,包括半路杀出来一个LevelDB,正在啃gorm框架。自己也实现了一个简单的压测框架,只用了不到20行,Go在多线程编程方面的确语法很简单。
有文为证:
- Golang语言HTTP客户端实践
- Java、Groovy、Python和Golang如何把方法当作参数
- Golang fasthttp实践
- Go语言HTTPServer开发的六种实现
- Go WebSocket开发与测试实践【/net/websocket】
- LevelDB Java&Go实践
- Go WebSocket开发与测试实践【gorilla/websocket】
- Java&Go三种HTTP客户端性能测试
- Java&Go三种HTTP服务端端性能测试
Java&Groovy
本年度Java水平好像没啥进展,一直在原地踏步,唯一比较欣慰的就是阅读源码的能力有所提高,当然还得借助翻译软件的帮助。Groovy好像也没啥提高,只是在写代码时候更加熟练了各种乱七八糟的闭包,通俗来讲,代码可读性更差了。
有文为证:
- 利用Java反射处理private变量
- 复杂JSON结构创建语法
- 又双叒叕一行代码:Map按值排序
- Groovy反射invokeMethod传参实践
- Groovy参数默认值在接口测试中应用
- Java、Groovy、Python和Golang如何把方法当作参数
- Groovy动态添加方法和属性及Spock单测
- 给JSONObject添加自定义遍历方法
- Groovy热更新Java实践
异步关键字
受Go语言异步关键字go的启发,我也写了一个Java和Groovy使用的一步关键字fun,通过闭包完成方法传递,使用预先定义好的线程池完成异步任务的执行,然后通过守护线程的特性,在所有任务代码结束后,关闭线程池。
有文为证:
这里忍不住秀一下:
def ft = {
output("创建线程")
fun {
int i = 0
ringBuffer.publishEvent {e, s ->
e.setRequest(getHttpPost(url,params))
}
i++
}
}
}
5.times {ft()}
单元测试
这里太多泪,不想说了。等我从坑里爬出来,发一些Spock实践的内容。
业余技能
今年业务技能收获颇丰,我学会了做表情,自我感觉良好,现在做了50+个,自我感觉良好,有兴趣的可以加我私聊获取FunTester系列表情包。
顺带着也学会了简单的视频剪辑,间接促进我录制一些教程视频,也是拓展了输出内容的形式。通过录制视频也算是锻炼了自己的对着屏幕讲话的能力,现在基本上可以连贯做到10-15分钟的不间断吹水。这方面有兴趣的可以一起切磋一下。
有文为证:
- 动态压测模型动态增减功能演示
- Automa基础功能演示
- DelayQueue基础功能演示
- ThreadLocal类基础功能演示
- Groovy相比Java语法简洁性
- 如何在JMeter中操作Redis
- 使用Groovy metaclass进行Java热更新演示
- 控制台彩色输出
- 反射访问和修改private变量
- Java线程同步三剑客之CountDownLatch
- Java线程同步三剑客之CyclicBarrier
- Java线程同步三剑客之Phaser
- Disruptor高性能队列常用API演示