【问题标题】:Measure Spring RestTemplate HTTP request time测量 Spring RestTemplate HTTP 请求时间
【发布时间】:2012-11-08 10:04:00
【问题描述】:

我想测量 RestTemplate.getForObject 调用的 HTTP GET 请求的时间,而不需要解析响应所需的时间。所以只是远程 HTTP 调用需要的时间。我已经尝试设置ClientHttpRequestInterceptor,但我认为这不是正确的方法,因为时间似乎是错误的:

public class PerfRequestSyncInterceptor implements ClientHttpRequestInterceptor {
private Logger log = Logger.getLogger(this.getClass());

@Override
  public ClientHttpResponse intercept(HttpRequest request, byte[] body,
        ClientHttpRequestExecution execution) throws IOException {

    long start = System.nanoTime();
    ClientHttpResponse resp = execution.execute(request, body);

    log.debug("remote request time: "
            + ((System.nanoTime() - start) * Math.pow(10, -9)));
    return resp;
  }
}


致电:

RestTemplate rest = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new PerfRequestSyncInterceptor());
rest.setInterceptors(interceptors);

Response inob = rest.getForObject(xmlURL, Response.class);

如何测量 RestTemplate HTTP 请求的时间?

【问题讨论】:

  • 我遇到了同样的问题。您需要对响应对象进行方法调用以阻止执行,直到响应可用为止。

标签: java performance web-services spring http


【解决方案1】:

您可以使用 AOP 和 Spring 内置的 PerformanceMonitorInterceptor。您需要正确定义要拦截哪些类的哪些方法,然后才能测量。你可以像这样配置它:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans      
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    <bean id="springMonitoredService"
        class="com.myorg.service.springmon.MyServiceSpringImpl"/>


    <bean id="springMonitoringAspectInterceptor"        
class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor">
        <property name="loggerName"     
                value="com.myorg.SPRING_MONITOR"/>      
    </bean>


    <aop:config>
            <aop:pointcut id="springMonitoringPointcut"
                   expression="execution(* java.net.HttpURLConnection.connect(..))"/>




                <aop:advisor pointcut-ref="springMonitoringPointcut" 
            advice-ref="springMonitoringAspectInterceptor"/>      
    </aop:config>

</beans>

【讨论】:

  • 我应该配置哪种测量方法?
  • 内部 RestTemplate 使用 java.net.HttpURLConnection 你需要测量 connect() 方法。此外,您也可以尝试 getDoOutput() 方法
  • 我可以请您更新您的答案以指向此方法吗?
  • 这对我不起作用。但是,如果我将表达式更改为使用休息模板的类的公共方法,它就可以工作。我的模板版本没有使用 HttpURLConnection 吗?
【解决方案2】:

您可以使用秒表来做到这一点。

public class PerfRequestSyncInterceptor implements ClientHttpRequestInterceptor {

    private final static Logger LOG = LoggerFactory.getLogger(PerfRequestSyncInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest hr, byte[] bytes, ClientHttpRequestExecution chre) throws IOException {
        StopWatch stopwatch = StopWatch.createStarted();
        ClientHttpResponse response = chre.execute(hr, bytes);
        stopwatch.stop();

        LOG.info("method=" + hr.getMethod() + ", uri="+hr.getURI() + ", response_time=" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + ", response_code=" + response.getStatusCode().value());

        return response;
    }
}

并且在restTemplate被实例化的类中

private final List<ClientHttpRequestInterceptor> requestInterceptors = new ArrayList<>();
requestInterceptors.add(new PerfRequestSyncInterceptor());
this.restTemplate.setInterceptors(requestInterceptors);

为maven添加秒表依赖:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>r05</version>
</dependency>

【讨论】:

  • 感谢您的回答。我试过了,但没有达到预期的效果。可能是因为春天的变化(我没有调查)。只是想把它放在这里警告其他人这样做时不要依赖结果。我在调试模式下向服务器发出了一个请求,所以我不得不在服务器上按 2 次恢复,但拦截器测量了 1ms 作为时间 - 这简直是不可能的。
  • @J.R. 口述我面临同样的问题。不要使用这个
【解决方案3】:

我想测量一个 HTTP GET 请求的时间 RestTemplate.getForObject 调用没有解析所需的时间 回应

我也有同样的要求。我想知道服务器响应时间来衡量服务器在没有任何 RestTemplate 响应处理的情况下响应需要多长时间。我用地图向HttpClientBuilder 添加了两个拦截器,这样我就可以测量低级别请求和响应之间的时间。

HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

// Attach interceptors
ResponseTimeInterceptor interceptor = new ResponseTimeInterceptor();
httpClientBuilder.addInterceptorFirst( (HttpRequestInterceptor) interceptor );
httpClientBuilder.addInterceptorFirst( (HttpResponseInterceptor) interceptor );

// Use client with RestTemplate or on its own
HttpClient client = httpClientBuilder.build();

这是最小的双重任务拦截器:

public class ResponseTimeInterceptor implements HttpRequestInterceptor, HttpResponseInterceptor {
    private final Map<HttpContext, Long> requestMap = new MaxSizeHashMap<>( 50 );

    @Override
    public void process( HttpRequest httpRequest, HttpContext httpContext ) throws HttpException, IOException {
        requestMap.put( httpContext, System.currentTimeMillis() );
    }

    @Override
    public void process( HttpResponse httpResponse, HttpContext httpContext ) throws HttpException, IOException {
        long startTime = requestMap.getOrDefault( httpContext, 0L );
        long diff = System.currentTimeMillis() - startTime;
        System.out.println( "Response time: " + diff + "ms" );
    }
}

响应拦截器返回后,响应数据继续进入 RestTemplate 响应处理程序。

注意:MaxSizeHashMap 取自 https://stackoverflow.com/a/5601377

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2019-10-25
    • 2021-05-28
    • 2013-03-18
    • 2014-10-31
    • 2015-12-13
    相关资源
    最近更新 更多