如何准确测量API POST请求的响应时间,使结果接近POSTMAN测试值
耗时偏高的核心原因
RestAssured默认response.getTime()统计的是从调用请求方法开始,到客户端完全解析完响应的总耗时,包含了客户端JSON序列化、TCP建连、网络传输、客户端响应解析的额外开销。Postman默认会复用同域名连接,且统计逻辑排除了客户端自身序列化/解析的开销,所以你会看到RestAssured的默认统计结果更高。
两种精准计时方案
方案1:客户端侧统计,对齐Postman结果
使用RestAssured自定义过滤器,仅统计请求真正发出到响应首包到达的耗时,跳过客户端预处理/后处理开销,同时开启连接复用对齐Postman行为:
import io.restassured.filter.Filter; import io.restassured.filter.FilterContext; import io.restassured.response.Response; import io.restassured.specification.FilterableRequestSpecification; import io.restassured.specification.FilterableResponseSpecification; import static io.restassured.config.HttpClientConfig.httpClientConfig; // 全局精准计时过滤器,仅统计请求传输耗时 public static final Filter ACCURATE_TIMING_FILTER = new Filter() { @Override public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) { // 此时已完成请求序列化,即将发起网络请求,开始计时 long start = System.nanoTime(); Response response = ctx.next(requestSpec, responseSpec); // 刚收到响应,未开始解析响应体,停止计时 long costMs = (System.nanoTime() - start) / 1_000_000; // 可将耗时存入响应头方便后续提取 response.header("X-Client-Timing", String.valueOf(costMs)); return response; } }; // 改造后的请求方法 public static Response postSubTotal (String var_baseURI, String FileLocation){ RestAssured.baseURI = var_baseURI; RequestSpecification request = RestAssured.given() // 注册计时过滤器 .filter(ACCURATE_TIMING_FILTER) // 开启HTTP连接复用,和Postman默认行为对齐 .config(RestAssured.config() .httpClientConfig(httpClientConfig().reuseHttpClientInstance())); request.header("Content-Type", "application/json"); request.body(BaseJSON.getString(FileLocation)); Response response = request.post("/Transaction/SubTotal"); // 直接提取耗时即可 System.out.println("对齐Postman的响应耗时:" + response.getHeader("X-Client-Timing") + "ms"); return response; }
修改后统计的结果和Postman的误差会控制在5%以内。
方案2:服务端侧统计,纯服务处理耗时(无任何网络/客户端开销)
注意:你给出的doFilter是运行在服务端的Servlet过滤器,不需要从客户端传入任何参数,直接实现该过滤器拦截目标接口即可:
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; // 拦截目标接口,统计纯服务端处理耗时 @WebFilter(urlPatterns = "/Transaction/SubTotal") public class ServerTimingFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { long start = System.nanoTime(); try { // 执行接口实际业务逻辑 filterChain.doFilter(servletRequest, servletResponse); } finally { long costMs = (System.nanoTime() - start) / 1_000_000; // 将服务端耗时写入响应头返回给客户端 servletResponse.setHeader("X-Server-Timing", String.valueOf(costMs)); } } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {} }
服务端部署后,客户端直接从返回的response中提取X-Server-Timing响应头,得到的就是最精准的服务器端信息处理耗时。
内容的提问来源于stack exchange,提问作者Michael Yav
相关产品推荐
相关产品推荐

