Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Web服务请求执行时间计算_Java_Cxf - Fatal编程技术网

Java Web服务请求执行时间计算

Java Web服务请求执行时间计算,java,cxf,Java,Cxf,我用Java中的CXF实现了一个工作的SOAP web服务。在服务器端计算方法执行的好方法是什么 我现在做的是使用拦截器。我已经在我的InInterceptor(Phase.RECEIVE)中定义了公共静态长启动。在我的OutiterCeptor(Phase.SEND)中,我计算响应时间如下: @Override public void handleMessage(Message arg0) { long stop = System.currentTimeMill

我用Java中的CXF实现了一个工作的SOAP web服务。在服务器端计算方法执行的好方法是什么

我现在做的是使用拦截器。我已经在我的InInterceptor(Phase.RECEIVE)中定义了
公共静态长启动
。在我的OutiterCeptor(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");
    }
有更好的方法吗?我读过关于通过代理执行方法的文章,但我不知道如何去做

问题更新:

我在谷歌上搜索了更多关于使用代理的第二种方法的信息,即:

@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;
         }
    }

根据到目前为止对这个问题的评论,使用拦截器比使用代理要好。我希望尽可能降低Web服务的速度(这肯定会降低速度)同时获得精确的性能度量。

我不推荐您使用InInterceptor和OutInterceptor的第一种方法-原因是没有干净的方法来存储starttime-将其存储在静态变量中的方法在线程环境中不起作用

第二种使用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.");
}
并在为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>

CXF服务器
org.apache.cxf.transport.servlet.CXFServlet
CXF服务器
/网络服务/*
执行时间过滤器
/网络服务/*
要求

我认为拦截器可以在
消息
对象中放入任意数据,因此您可以将开始时间存储在那里,然后再将其取出以计算经过的时间

// in your receive interceptor
@Override
public void handleMessage(Message message) {
    long startTime = System.currentTimeMillis();
    message.put("my.timing.start", startTime);
}

CXF在消息映射中存储自己的一些数据,但它的大多数键都以
org.apache.CXF
javax.xml.ws
开头,因此您可以使用一个拦截器的完全限定类名使映射键唯一

在服务器端计算方法执行

使用
拦截器
您也在测量
CXF

我的意思是,
拦截器
用于预处理/后处理与应用程序逻辑相关的消息。
使用
拦截器
您的测量包括CXF流链的一部分。
如果这是您想要的,那么可以。
但是如果你想测量你的方法执行情况,你应该把时间间隔与你的方法联系起来。

基于我计算出的以下内容。关键是在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");
        }
    }       
}
公共类IncomingInterceptor扩展AbstractPhaseInterceptor{
公共收入拦截器(){
超级(相位接收);
}
@凌驾
public void handleMessage(Message msg)引发错误{
long startTime=System.currentTimeMillis();
msg.put(“my.timening.start”,startTime);
}
}
公共类OutgoingInterceptor扩展了AbstractPhase Interceptor{
Logger log=LoggerFactory.getLogger(AbstractPhaseInterceptor.class);
公共支出接受者(){
super(Phase.SEND);
}
@凌驾
public void handleMessage(Message msg)引发错误{
Long startTime=(Long)msg.getExchange().getInMessage().remove(“my.timing.start”);
if(startTime!=null){
long executionTime=System.currentTimeMillis()-startTime;
log.info(“执行时间为~”+执行时间+“毫秒”);
}否则{
日志信息(“未找到计时器”);
}
}       
}

我认为上面的机制很好。我建议使用拦截器,我尝试过了,但它不起作用,使用message.put()在接收拦截器中存储的对象无法通过message.put在发送拦截器中使用。与其将请求开始时间信息存储在message对象中,您可以将其推入ThreadLocal,然后在出站拦截器中检索它。+1确实非常有用。注意:如果您使用的是Spring安全性,请注意它也是通过过滤器应用的,您需要注意过滤器的顺序,以确保您也对安全层进行计时(或者不计时,取决于您想要什么)。我认为您需要使用msg.getExchange().put/remove?
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");
        }
    }       
}