freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

一次接口的性能优化之旅
京东云技术团队 2024-04-08 16:29:14 100721

一、引言

在项目开发过程中,我们经常会遇到接口响应慢的问题。这不仅影响了用户体验,还可能降低了系统的吞吐量。为了提高接口性能,我们需要对整个系统进行全面的优化,包括代码层面、数据库、缓存、异步处理等方面。本文将分享一个接口性能优化之旅,希望能帮助大家掌握Pfinder使用、JSF异步调用等优化技巧,提升接口性能和定位问题的能力。

二、现状诊断

UMP诊断:

Max:10s

T99:1000ms

经常可用率下降



Pfinder诊断:

问题1:循环调用RPC 120次=1441ms

问题2:查询DB 286ms

问题3:未知操作 2000ms+


三、问题定位以及性能优化

如何解决Pfinder显示耗时不全问题:-> 手动完善全程跟踪上报

1.集成Pfinder SDK:

<!-- 引用 PFinder SDK 库 -->
<dependency>
    <groupId>com.jd.pfinder</groupId>
    <artifactId>pfinder-profiler-sdk</artifactId>
    <version>1.2.2-FINAL</version>
</dependency>

1.使用注解:@PFTracing


1.上报效果


1.定位问题和进行代码分析


这段代码的目的是从一个名为waveInfos的字符串列表中,筛选出已经包含在另一个名为sendDPackageCodes的字符串列表中的元素,并将这些重复的元素放入一个新的列表repeatResult中。然后,它从waveInfos中排除这些重复的元素,将剩余的元素放入另一个新的列表showPackages中。这两个列表最终被用于前端显示或进一步处理。简而言之,这段代码的作用是去重并筛选出尚未处理的数据。

通过现象查看此处代码耗时占总耗时进一半左右,因此判断集合数据非常多,导致数据计算耗时较长。通过日志打印发现:waveInfos=3000+,sendDPackageCodes=7000+,因此可以看出两个集合因为数据过大导致耗时较长。


代码优化:使用Set进行处理



优化效果:2000ms -> 6ms

如何解决RPC批量调用问题 -> 使用JSF异步调用

同步异步方案比较

优劣势 异步调用 同步调用
优势 提高系统的并发性能 简单直观
提高系统的响应速度 错误处理方便
节约资源
劣势 复杂性 阻塞线程
可读性差 响应速度慢

JSF异步调用使用

第一步:如果存在同步bean,为了不影响同步bean可以注入新的异步bean。需要

注意:jsf 这边相同接口 别名 最多支持3个

// 同步bean
@Autowired
private XxxxxApi xxxxApi;
// 异步实现bean,(jsf 这边相同接口 别名 最多支持3个)
@Autowired
private XxxxxApi xxxxAsyncApi;

<!-- 【异步】路由查询班次单号明细 -->
<jsf:consumer id="xxx" interface="xxx"
              protocol="jsf" alias="xx" timeout="xxx" retries="0" check="false">
    <jsf:method name="方法名称" async="true"/>
</jsf:consumer>

第二步:使用RpcContext调用,返回CompletableFuture对象

// Rpc代理类 需要返回CompletableFuture 对象
public CompletableFuture<CommonDto<PageDto>> queryWaybillDetailByBusinessIdByAsync() {
    // 发起方法请求
    return RpcContext.getContext().asyncCall(() -> xxxxAsyncApi.method());;
}

第三步:调用处任意地方,获取future返回结果,需要指定超时时间

public <T> T getResultDefaultTimeOut(CompletableFuture<T> future) {
    try {
        return future.get(10, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        throw new RuntimeException(e);
    }
}

优化效果:1400ms -> 200ms

五、最终效果和未解决问题

优化前优化后

问题 优化前 优化后 方案
总耗时 3800ms 500ms
rpc循环调用 1400ms 200ms JSF异步调用(N次耗时变一次最大耗时)
数据笛卡尔积处理 2000ms 6ms list包含操作变set包含操作
数据库操作 100ms 100ms 数据库批量查询,此期不处理
未知操作 150ms 150ms 非业务代码,怀疑是sql查询后结果处理,目前无法跟踪和处理,此期不处理

六、总结

接口性能优化是一个涉及多个方面的过程,需要从代码层面、数据库、缓存、异步处理等多个维度进行优化。在这个过程中,我们需要不断诊断瓶颈、尝试优化手段,并结合实际情况进行调整。希望通过本文的分享,大家能掌握接口性能优化的方法和技巧,提高接口性能,提升用户体验。

# 接口
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 京东云技术团队 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
京东云技术团队 LV.10
最懂产业的云
  • 1750 文章数
  • 91 关注者
京东中台化底层支撑框架技术分析及随想
2025-04-08
Web Components实践:如何搭建一个框架无关的AI组件库
2025-04-08
计算机网络协议介绍
2025-04-08
文章目录