将一个接口响应时间从2s优化到 200ms以内的一个案例
2020/3/2 8:15:34
本文主要是介绍将一个接口响应时间从2s优化到 200ms以内的一个案例,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、背景
在开发联调阶段发现一个接口的响应时间特别长,经常超时,囧…
本文讲讲是如何定位到性能瓶颈以及修改的思路,将该接口从 2 s 左右优化到 200ms 以内 。
二、步骤
2.1 定位
定位性能瓶颈有两个思路,一个是通过工具去监控,一个是通过经验去猜想。
2.1.1 工具监控
就工具而言,推荐使用 arthas ,用到的是 trace 命令
具体安装步骤很简单,大家自行研究。
我的使用步骤是,先最终待研究的函数的最外层:
trace com.xxx.service.impl.AServiceImpl refresh
其中耗时最多的子函数会被标红色
Affect(class-cnt:2 , method-cnt:2) cost in 525 ms. `---ts=2020-0X-0Y 13:33:18;thread_name=DubboServerHandler-127.0.0.1:20880-thread-36;id=24e;is_daemon=true;priority=5;TCCL=com.mmm.WWWClassLoader@4362d7df `---[1761.834357ms] com.xxx.service.impl.AServiceImpl$$EnhancerBySpringCGLIB$$e3cd7543:refresh() +---[0.017066ms] com.xxx.service.impl.AServiceImpl$$EnhancerBySpringCGLIB$$e3cd7543:$jacocoInit() `---[1761.00347ms] org.springframework.cglib.proxy.MethodInterceptor:intercept() `---[1757.647111ms] com.xxx.service.impl.AdServiceImpl:refresh() +---[0.006629ms] com.xxx.biz.yyy.service.impl.AServiceImpl:$jacocoInit() +---[0.004073ms] java.util.Collections:singletonList() +---[1709.203302ms] com.yyy.service.impl.AServiceImpl:refreshSomeThings() `---[48.135719ms] com.yzzzz.service.impl.AServiceImpl:createSurvey()
继续再 trace 耗时最多的子函数。
trace com.yyy.service.impl.AServiceImpl refreshSomeThings
最终定位到最影响耗时的函数上,继续往下跟。
最后发现造成性能瓶颈的函数是一个网络请求,单次请求大概 100多毫秒。
为了避免调用的数据量太大,项目中采用分批调用的方式,但是每个批次太小,导致请求次数过多。
假设请求 N 次(如 10次),每次请求 M毫秒(如 200ms),总耗时就是 N*M (2000)毫秒。
2.1.2 猜想
如果开发经验足够丰富,大致可以猜出哪些接口可能存在性能问题。
最常见的有:
- 慢 SQL 会是性能瓶颈,主要原因是没有命中索引。
- 发送远程数据请求(RPC 远程调用、HTTP 远程调用)。
- I/O 操作等。
然后审查一下自己的代码发现 SQL 查询部分都可以命中索引,调用链路上有一个函数最终会调用 HTTP 请求,而且是在一个循环里。
因此最有可能成为造成接口延时的是底层依赖的 HTTP 请求。
2.2 解决
既然 HTTP 请求是性能瓶颈,那么要尽量减少请求,或者让请求由串行改为多线程并发/并行。
减少网络请求的次数,可以将多个请求合并成一个批量接口(或者增加批量请求的每个批次的大小)。
这里的批次甚至可以使用动态配置,根据情况动态修改。
将串行改为并行可以使用 CompletableFuture
来实现,具体参见:《Java 数据分批调用接口的正确姿势》
最终一个接口的响应时间从1 s - 2 s降低到了 200 ms 以内。
3、总结
很多人不愿意学习 arthas ,如果不去学习不去了解,遇到可以用上的场景想不起来去用。
另外大家可以积累下开发过程中常见的性能瓶颈的原因,以便未来遇到性能瓶颈是可以快速排查和解决问题。
最后大家在开发阶段或测试阶段,多看错误日志,多关注接口的响应时长等,尽早排除问题,尽早做优化。
希望本文对大家
这篇关于将一个接口响应时间从2s优化到 200ms以内的一个案例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南
- 2024-09-30Dnd-Kit学习:新手快速入门指南