2012-05-08 12 views
12

मैं एक काम कर सोप वेब सेवा जावा में CXF साथ लागू किया है। सर्वर पक्ष पर विधि निष्पादन की गणना करने का एक अच्छा तरीका क्या होगा?वेब सेवा अनुरोध exection समय गणना

मैं के लिए क्या किया है अब मैं इंटरसेप्टर का इस्तेमाल किया है। मैंने अपने इनइंटरसेप्टर (Phase.RECEIVE) में public static long start परिभाषित किया है। और मेरे 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"); 
    } 

वहाँ यह करने के लिए एक बेहतर तरीका है? मैं विधि गड़बड़ी प्रॉक्सी के निष्पादन के बारे में पढ़ रहा था, लेकिन मुझे कोई संकेत नहीं है कि यह कैसे करें।

प्रश्न अद्यतन:

मैं थोड़ा अधिक एक प्रॉक्सी यानी का उपयोग कर दूसरी तरह से arround मेरी रास्ता खोजने googled है:

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

इस सवाल का टिप्पणियां अब तक के आधार पर, इंटरसेप्टर उपयोग कर रहा है प्रॉक्सी का उपयोग करने से बेहतर है। मैं जितना संभव हो सके webservice को धीमा करना चाहता हूं (यह निश्चित रूप से इसे धीमा कर देगा) और साथ ही साथ एक सटीक प्रदर्शन माप प्राप्त करें।

+0

मुझे लगता है कि उपर्युक्त तंत्र अच्छा है। –

+0

मैं वास्तव में _very_ सहायक होने के लिए इंटरसेप्टर्स की भी सिफारिश करता हूं, – mtraut

उत्तर

10

मैं इनइंटरसेप्टर और आउटइंटरसेप्टर का उपयोग करने के आपके पहले दृष्टिकोण की अनुशंसा नहीं करता - कारण यह है कि स्टार्टटाइम को स्टोर करने का कोई साफ तरीका नहीं है - जिस दृष्टिकोण को आपने स्थिर वैरिएबल में स्टोर करने के लिए टोकन किया है वह थ्रेड में काम नहीं करेगा वातावरण।

एओपी का उपयोग करने का आपका दूसरा दृष्टिकोण बहुत अच्छा है, हालांकि यह सीएक्सएफ स्टैक में बिताए गए समय को नहीं देगा, यह केवल आपके सेवा स्तर पर आने के बाद ही समय प्रदान करेगा।

मैं सबसे अच्छा तरीका एक सर्वलेट फिल्टर का उपयोग किया जाएगा लग रहा है, तो आप ऐसा कर सकते हैं:

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."); 
} 

और एक ही uri जहां CXFServlet के लिए मानचित्रण प्रदान की है पर मानचित्रण प्रदान करते हैं।

यह बहुत अधिक क्लीनर होना चाहिए। आपको और भी सूक्ष्म कुछ चाहते हैं, तो आप अपने 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> 
+0

+1। एक नोट: यदि आप स्प्रिंग सिक्योरिटी का उपयोग कर रहे हैं, तो ध्यान रखें कि इसे फ़िल्टर के माध्यम से भी लागू किया जाता है और आपको यह सुनिश्चित करने के लिए फ़िल्टर के क्रम से सावधान रहना होगा कि आप सुरक्षा परत का समय भी दे रहे हैं (या नहीं, निर्भर करता है आप क्या चाहते हैं)। –

3

मुझे लगता है कि इंटरसेप्टर Message वस्तु में मनमाने ढंग से डेटा रख सकते हैं, तो आप वहाँ प्रारंभ समय की दुकान और बाद में वापस बाहर समय बीत गणना करने के लिए मिल सकता है।

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

// in your send interceptor 
@Override 
public void handleMessage(Message message) { 
    Long startTime = message.remove("my.timing.start"); 
    if (startTime != null) { 
     long executionTime = System.currentTimeMillis() - startTime; 
     System.out.println("execution time was ~" + executionTime + " ms"); 
    } 
} 

CXF भंडार संदेश नक्शे में अपने स्वयं के डेटा के कुछ है, लेकिन इसकी चाबियों का सबसे org.apache.cxf या javax.xml.ws के साथ शुरू है, तो आप सिर्फ में से एक के पूर्णत: योग्यता वर्ग के नाम का उपयोग करके कुंजी अद्वितीय अपने नक्शे बना सकते हैं आपके interceptors। एक सर्वर साइड पर

+0

मैंने कोशिश की, और यह काम नहीं करेगा, इंटरसेप्टर प्राप्त करने में message.put() का उपयोग करके संग्रहीत ऑब्जेक्ट्स इंटरसेप्टर भेजने में message.put के माध्यम से उपलब्ध नहीं हैं। –

+0

संदेश ऑब्जेक्ट में अनुरोध समय की जानकारी संग्रहीत करने के बजाय, आप थ्रेडलोकल में धक्का दे सकते हैं और फिर इसे आउटबाउंड इंटरसेप्टर में पुनर्प्राप्त कर सकते हैं। –

0

कैलकुलेट प्रणाली निष्पादन?

Interceptors का उपयोग करके आप CXF माप रहे हैं और साथ ही!
मेरा मतलब है Interceptors एप्लिकेशन तर्क के संबंध में एक संदेश को पूर्व/पोस्ट करने के लिए उपयोग किया जाता है।
Interceptor का उपयोग करके आपके माप में प्रवाह की सीएक्सएफ श्रृंखला के कुछ भाग शामिल हैं।
यदि यह वही है जो आप चाहते हैं तो ठीक है।
लेकिन यदि आप अपनी विधि निष्पादन को मापना चाहते हैं तो आपको अपनी विधि के संबंध में समय अंतराल रखना चाहिए।

4

matts' answer के आधार पर मैंने निम्नलिखित कार्य किया। कुंजी यह है कि आउटगोइंग इंटेसेप्टर में आपको आने वाले संदेश प्राप्त करने की आवश्यकता है और उस से प्रारंभिक टाइमस्टैम्प प्राप्त करें।

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"); 
     } 
    }  
} 
+0

मुझे लगता है कि आपको msg.getExchange() का उपयोग करने की आवश्यकता है। डाल/हटाएं? – jontejj

+0

धन्यवाद यह मेरे लिए काम किया :) – Niamath

संबंधित मुद्दे