作为一名深陷在增删改查泥潭中练习时长三年的夹娃练习生,偶尔会因为没有开发任务不知道周报写什么而苦恼。
正愁这周写啥呢,组长过来交代了个跟进第三方公司性能测试报告的工作,我一寻思这活不最好干了吗,正愁不知道周报咋写呢,又能提现工作量又不累,本以为轻松拿捏的结果差点让老弟翻车。
由于我们组主要做数仓管理这块的业务,这次的性能测试上有一些数据服务并发相关的指标需要后端配合测试,让一天搞定,我寻思半天搞完还能去掘金狠狠的摸半天鱼,岂不美哉。拿到测试指标之后直接手心出汗了。
啥意思,亿级数据查询毫秒级响应还要100并发持续5分钟,家人们谁懂啊。。。关键我们负责的业务是tob的场景啊,哪有这么高并发。数据查询还在旧的python服务里,给提供的测试环境全是单机服务。
加缓存
既然是做性能测试那管数据对不对什么事,给你返回不就行了,在服务加个临时缓存,先把数据查询的耗时降下来再考虑其他的。
身为一个Javaboy,写python的代码10行代码得5行问chatGPT,好在是用redis加上了缓存。用jmeter浅试一下,
效果上看加上缓存查询速度的确变快了,但是平均耗时离预期还是差距较大,最大耗时要接近5s多,看来只加缓存是扛不住,耗时应该是服务扛不住并发,线程阻塞了。。。
nginx横向扩展
不得不吐槽下,服务真垃圾呐,时间紧任务重,赶紧想办法,直接把问题当成面试题,脑袋里直接开始翻阅八股文,什么高内聚、低耦合、高吞吐、月薪3000包吃住,第一个冲出来的想法就是扩展服务做负载。
怎么负载呢,部署三份数据查询服务,nginx做upstream负载,效果应该顶得住,开搞开搞。结果python代码不太熟,多进程的方式启动torando就是报错。整的我满头大汗,下午就得给人提供接口了这咋整啊,不行问问组长去吧。
结果组长直接说浪费那时间干啥啊,反正都是做做样子,在nginx里写个lua脚本,读一下本地文件返回数据不就可以了,第三方又不会管你咋实现的...都得都懂。
lua脚本
我仔细一想也是,整那么紧张干啥,先实现了再说,由于环境里的nginx已经安装了lua插件可以直接使用。
先提前把请求的返回数据保存到txt里,然后用lua实现一个读取本地文件的方法,请求打过来之后判断body里的数据是否是指定的数据id,如果是直接读取数据返回。
nginx和lua的性能别说100并发了1w并发也轻松拿捏。
lua读取本地文件内容
lua
复制代码
function getFile(file_name) local f = assert(io.open(file_name, 'r')) local string = f:read("*all") f:close() return string end
找到nginx配置对应的请求url,添加access_by_lua_block代码块,将getFile方法声明在这里,并且写一下匹配逻辑,如果body中包含file_id,直接调用getFile方法返回,不包含还是走正常的查询逻辑。
php
复制代码
location = /api/data/preview { set $upstream 'fe_full_long'; access_by_lua_block { function getFile(file_name) local f = assert(io.open(file_name, 'r')) local string = f:read("*all") f:close() return string end ngx.req.read_body() local data = ngx.req.get_body_data() if ngx.re.match(ngx.var.request_body, "file_id") then ngx.say(getFile(string.format("/nginx/conf/conf.d/a.txt", f))); return end } proxy_pass http://$upstream; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
保存nginx -t,先检查后重启,防止手心冒汗,简单测了一下性能直接起飞,直接提供给第三方测试了。
亿级数据毫秒级响应?
晚上下班前发过来了初版的测试报告,组长一看,直接给我阅起兵来了,"你这也太快了,搂着点啊,管家指标还一样,快改改"。
我一看好家伙,亿级数据28毫米返回,雀氏有点尴尬了。。。。赶紧改改。在lua脚本里sleep随机几百毫秒就真实了。
lua
复制代码
-- 定义睡眠函数 local function sleep(ms) ngx.sleep(ms / 1000) end -- 随机睡眠一段时间(1毫秒到100毫秒之间) math.randomseed(ngx.now()) local sleepTime = math.random(1, 100) sleep(sleepTime)
重启下nginx重测,结果很合理,必须得在周报浓墨重彩一波。。。