2018年离开了自己工作过了7年的公司,从业务测试工作转变为测试开发,围绕公司的质量体系打造测试管理平台。跳出舒适区后,忙于新工作新挑战,有1年多没有发文章。近年底,工作计划也没有那么繁忙,可以有时间沉淀一下,记录自己在这次双十一工作中做的一套动态的mock服务。
前期背景
我们公司承接了某品牌方G的OMS业务,而G的WMS又包给了另外一家公司D。品牌希望OMS和WMS系统能分别做一次性能测试,要求如下:
1. 即各自走内部的流程进行性能测试,以期望在能在双十一期间能处理100万单/小时的吞吐量能力。
2. OMS这边来创建订单,WMS访问我们的文件系统获取订单文件。
3. 希望WMS发送订单状态:出库确认(shipment_confirm)和过仓反馈(transfer_order)时能够走我们公司的网络系统,以此来查看一下WMS的网络传输能力。
4. 订单内容分为多SKU订单和单个SKU订单,这种订单比例混合为30%,70%
5. 性能测试在生产环境下进行。
需求理解
1. 该阶段性能测试其实是针对D的;
2. 做Mock服务的目的是创建提供给D的测试订单数据;
3. 当D处理订单流程中会向OMS发送订单状态,Mock服务接收请求并返回响应;
也就是说,此时的Mock服务应该入下图:
设计方案
资源申请
1. 5台vm资源
2. 1个MySql单点
3. 用于外部访问的域名以及Nginx反向代理
技术实现
1. spring boot
实现功能
自动创建订单:
1. 为D的WMS生成约定格式的订单文件;(这些订单只能用于D的WMS测试使用)
2. 设置文件数量,当文件数量达到一定大小后才将这些文件打成一个压缩包tgz上传至文件服务器;
3. 通过接口命令去生成多SKU订单和单个SKU订单,数量可以由人为输入;
挡板功能:
1. 接收对方的过仓反馈(transfer_order)和出库确认(shipment_confirm)请求
2. 解析请求中的一些特定值构造成响应报文返回给D
3. 保证Mock Server的性能可靠
开发思路
1. 由测试人员输入创单命令,Mock程序开始创单
2. Mock服务从数据库里面获取一些必要的信息,例如上次创单号的最大值;
3. 创建了一张表记录订单号最大值,因为订单号是不允许重复的,所以记录下来,在下次创单时再读取它就可以保证不重复。
代码实现
实现接口:
1. /ship/create,有三个参数:
a) total: 一共需要产生多少订单;
b) unitSize: 每多少订单就生成一个tgz压缩包;
c) type: 多SKU订单还是单SKU订单;
2. /ship/send,将生成的订单tgz压缩包上传到文件服务器上
3. /logistics/service,挡板功能提供给D方调用发送状态请求,并根据它的状态请求返回相应的报文
以上就是定义的接口信息,由于具体实现涉及到一定的公司业务,所以只能大致讲述一下以上的思路。
题外话,在协助D公司进行性能测试时,一开始它们对我的Mock性能有所怀疑,因为它们的请求速度非常慢大约一小时只能处理20万单。
于是,我对自己的/logistics/service接口的使用jmeter对单台mock server进行了简单测试,该接口性能>350req/s,远远超过D公司的性能要求(100万单/小时),更不用说我的服务可以横向扩展以后的性能。再次,我将日志拿出来进行了分析发现,它们在发送请求时每个时间间隔最短为5秒,最长达到30秒,列出数据说明性能瓶颈不在我这边。
通过这件事,我很庆幸,我当时的日志打印还是比较完善的,才能够发现不是我的问题,不然对于一个新开发出来的服务在对外联调时,没有足够的日志支撑就会使自己的工作陷入被动。
总体来说,对外部分的Mock服务功能是非常简单的,开发运行过程也很顺利。而真正的重头戏才开始,那便是对内压测部分,请继续关注:开发Mock服务做双十一压测 (下)