前言
昨天的文章详细的介绍了mock,今天补充一个mock服务的实际使用场景——高并发性能测试时的依赖服务mock;
背景
最近在做一个项目的全链路压测,目的是验证服务有LB层、虚拟化层再到服务本身的性能情况,目标QPS是50w;这就带来一个问题,由于待测服务A有n个后端服务,且客户端请求数:后端服务请求数是1:n的,也就是说预期的50w的qps,对应后端的qps和就是n倍的50w;当然,测试过程不能使用线上服务,所以需要一个性能非常好的mock服务;
过程
之前分享过使用nginx cache来实现mock server,当然nginx cache也能完成这个任务,32核64G的linux,nginx的cache性能可以达到单机20w。
但使用nginx cache作为mock server有几个问题:
1、需要先cache真实的后端服务的response;
2、如果有多个接口需要mock的话,需要频繁的修改nginx配置;
3、如果有接口返回内容需要更新,需要删掉本地cache文件;
4、单机20w的qps,相比一般的网络框架,已经很高了,但是n×50w的qps,还是需要很多台nginx,才能完成;
为了解决上述几个问题,考虑用golang写一个mock服务,写了个架子测试了一下,查map的qps只能到6w多,还不如nginx,放弃;
google了一下高性能框架,发现一个叫japronto的python的网络框架,号称单机100w+的qps,写了个demo试了一下,确实没问题;详见github地址:https://github.com/squeaky-pl/japronto
引用一张性能对比:

自定义mock服务
需求1:单机100w的qps——使用japronto服务可实
需求2:自定义mock接口path——服务启动时读取DB内配置作为path
需求3:更新接口返回内容方便——前端页面支持增加&修改DB接口path配置
需求4:支持json结果&protobuf二进制结果——预置proto,自定义接口返回类型,服务初始化时做不同处理;
mock服务实现
服务启动 -> initData -> 根据type做不同处理,默认返回类型json,proto的话做二进制序列化;
DB字段:

实现简单前端页面完成接口内容修改:

用wrk验证一下测试服务性能:(抛开带宽限制)

32核机器,20个进程,qps可达98w,tp99<2ms;
实际使用
实际使用时,只需要同时部署5台20核虚机,或打包成镜像附属到测试集群,使用内网域名负载均衡到这五台机器(k8s集群的话使用域名映射),将被测服务的依赖服务地址改写成mock域名:端口/自定义path;
代码地址
https://github.com/lidedede/fastMock
整个工程100行左右代码,比较简陋,前端页面在另一个内部工程中完成,不好贴出来,大家可以自己实现,或者直接通过mysql客户端修改DB内容;
目前mock服务只支持单一接口对应单一mock结果,后续可以自定义多个value,在服务内随机返回;
使用场景
超高并发的中转服务测试场景,依赖服务数据稳定,被测服务无缓存(或测试过程中去掉缓存)