我有一个使用Java中的CXF实现的SOAP Web服务.在服务器端计算方法执行的好方法是什么?
我现在所做的是使用了拦截器.我public static long start在我的InInterceptor(Phase.RECEIVE)中定义了.在我的OutInterceptor(Phase.SEND)中,我计算响应时间如下:
@Override
public void handleMessage(Message arg0) {
long stop = System.currentTimeMillis();
long executionTime = stop - RequestStartInterceptor.start;
System.out.println("execution time was ~" + executionTime + " ms");
}
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?我正在阅读关于通过代理方法的执行,但我不知道如何做到这一点.
问题更新:
我用google搜索我的方式使用代理的第二种方式,即:
@Aspect
public class MyServiceProfiler {
@Pointcut("execution(* gov.noaa.nhc.*.*(..))")
public void myServiceMethods() { }
@Around("myServiceMethods()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("Going to call the method.");
Object output = pjp.proceed();
System.out.println("Method execution completed.");
long elapsedTime = System.currentTimeMillis() - start;
System.out.println("Method execution time: " + elapsedTime + " milliseconds.");
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
根据目前对此问题的评论,使用拦截器比使用代理更好.我希望尽可能减慢网络服务的速度(这肯定会减慢速度),同时获得精确的性能测量.
Bij*_*men 10
我不建议您使用InInterceptor和OutInterceptor的第一种方法 - 原因是没有干净的方法来存储启动时间 - 您将令牌存储在静态变量中的方法将无法在线程环境中工作.
您使用AOP的第二种方法非常好,但它不会花费在CXF堆栈上花费的时间,它只会在呼叫到达您的服务层时提供时间.
我觉得最好的方法是使用servlet过滤器,你可以这样做:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
long start = System.currentTimeMillis();
chain.doFilter(request, response);
long elapsedTime = System.currentTimeMillis() - start;
System.out.println("Method execution time: " + elapsedTime + " milliseconds.");
}
Run Code Online (Sandbox Code Playgroud)
并在您为CXFServlet提供映射的同一uri中提供映射.
这应该更清洁.如果您想要更精细的内容,可以将此方法与AOP方法混合以查找总体响应时间,然后将其分解为单个服务方法时间.
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservices/*</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>ExecTimeFilter</filter-name>
<url-pattern>/webservices/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
根据matts的回答,我得出了以下结论.关键是在OutgoingInterceptor中,您需要获取传入消息并从中获取开始时间戳.
public class IncomingInterceptor extends AbstractPhaseInterceptor<Message> {
public IncomingInterceptor() {
super(Phase.RECEIVE);
}
@Override
public void handleMessage(Message msg) throws Fault {
long startTime = System.currentTimeMillis();
msg.put("my.timing.start", startTime);
}
}
public class OutgoingInterceptor extends AbstractPhaseInterceptor<Message> {
Logger log = LoggerFactory.getLogger(AbstractPhaseInterceptor.class);
public OutgoingInterceptor() {
super(Phase.SEND);
}
@Override
public void handleMessage(Message msg) throws Fault {
Long startTime = (Long)msg.getExchange().getInMessage().remove("my.timing.start");
if (startTime != null) {
long executionTime = System.currentTimeMillis() - startTime;
log.info("execution time was ~" + executionTime + " ms");
} else {
log.info("timer not found");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9997 次 |
| 最近记录: |