Backend Development 7 min read

Comprehensive API Performance Optimization: Diagnosis, Problem Localization, and Solutions with Pfinder and JSF Asynchronous Calls

This article details a comprehensive API performance optimization journey, covering current diagnostics with Pfinder and UMP, pinpointing bottlenecks such as excessive RPC loops and large data sets, and presenting solutions like Set-based deduplication, JSF asynchronous calls, and code refactoring that reduce latency from seconds to milliseconds.

JD Tech
JD Tech
JD Tech
Comprehensive API Performance Optimization: Diagnosis, Problem Localization, and Solutions with Pfinder and JSF Asynchronous Calls

In this year's agile team building, the author leveraged a Suite executor for one‑click automated unit testing and began exploring other executors beyond JUnit, initiating a performance‑focused Runner investigation.

The current state diagnosis reveals that MCube loads templates based on cache status, converting products into a view‑tree before expression and event parsing. UMP metrics show a maximum response time of 10 s, T99 of 1000 ms, and frequent availability drops. Pfinder diagnostics expose three main issues: a looped RPC call executed 120 times taking 1441 ms, a database query costing 286 ms, and an unknown operation exceeding 2000 ms.

To address these problems, the author first replaced a costly list‑based deduplication with a Set implementation, cutting processing time from 2000 ms to 6 ms. The Maven dependency for integrating the Pfinder SDK is:

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

For RPC batch calls, the solution switches to JSF asynchronous invocation. The steps include defining separate synchronous and asynchronous beans:

// 同步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>

The asynchronous RPC proxy returns a CompletableFuture :

public CompletableFuture<CommonDto<PageDto>> queryWaybillDetailByBusinessIdByAsync() {
    // 发起方法请求
    return RpcContext.getContext().asyncCall(() -> xxxxAsyncApi.method());
}

And the caller retrieves the result with a timeout:

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

These optimizations reduced the RPC batch latency from 1400 ms to 200 ms and the overall interface response from several seconds to sub‑second levels, though some issues remain unresolved.

In conclusion, interface performance optimization requires a multi‑dimensional approach—code refactoring, efficient data structures, asynchronous processing, and thorough diagnostics—to significantly improve throughput and user experience.

backendJavaPerformance OptimizationasynchronousAPIJSFPfinder
JD Tech
Written by

JD Tech

Official JD technology sharing platform. All the cutting‑edge JD tech, innovative insights, and open‑source solutions you’re looking for, all in one place.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.