2012-11-07 27 views
15

Jetty पर चल रहे secure web service का परीक्षण करने के लिए JERSEY Client + HTTPS के साथ JUnit परीक्षण का उपयोग कर रहा हूं। पर मेरी कॉल में से एक 9-10 requests के प्रत्येक ब्लॉक के बाद 10 सेकंड के लिए लटकती है। समकक्ष Apache client कोड कुछ मिलीसेकंड में चलाता है। अगर मैं Jetty to HTTP मोड स्विच करता हूं तो समस्या गायब हो जाती है।जर्सी क्लाइंट HTTPS प्रदर्शन समस्या

मैं Jersey bundle & client 1.14 and Jetty 6.1.26



उपयोग कर रहा हूँ अपाचे ग्राहक काम करता है

@Test 
public void testApacheClient() throws Exception 
{ 
    HttpClient client = new HttpClient(); 
    ProtocolSocketFactory socketFactory = new EasySSLProtocolSocketFactory(); 
    Protocol https = new Protocol("https", socketFactory, 443); 
    Protocol.registerProtocol("https", https); 

    //Finishes in < 1 second 
    for (int i = 0; i < 30; i++) 
    { 
    GetMethod getMethod = new GetMethod("https://localhost:8443/home"); 
    client.executeMethod(getMethod); 
    String entity = getMethod.getResponseBodyAsString(); 
    getMethod.releaseConnection(); 
    } 
} 



जर्सी ग्राहक लटकी हुई है

@Test 
public void testJerseyClient() throws Exception 

    HostnameVerifier hv = getHostnameVerifier(); 
    ClientConfig config = new DefaultClientConfig(); 
    SSLContext ctx = getSslContext(); 
    config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, 
     new HTTPSProperties(hv, ctx)); 

    Client jerseyClient = Client.create(config); 

    //Finishes in < 1 second 
    for (int i = 0; i < 30; i++) 
    { 
    WebResource wr = jerseyClient.resource("https://www.google.com"); 
    ClientResponse cr = wr.get(ClientResponse.class); 
    String entity = cr.getEntity(String.class); 
    cr.close(); 
    } 

    /* Pauses for 10 seconds after the 10th request, and subsequently after every 9th request. 
    Debugging shows waiting at line 'ClientResponse cr = ...' 
    */ 
    for (int i = 0; i < 30; i++) 
    { 
    WebResource wr = jerseyClient.resource("https://localhost:8443/home"); 
    ClientResponse cr = wr.get(ClientResponse.class); //10 second pause after requests 9, 18, 27 
    String entity = cr.getEntity(String.class); //This is triggering the problem 
    cr.close(); 
    } 

    //Finishes in < 1 second 
    for (int i = 0; i < 30; i++) 
    { 
    WebResource wr = jerseyClient.resource("https://localhost:8443/home"); 
    ClientResponse cr = wr.get(ClientResponse.class); 
    cr.close(); 
    } 
} 

लगते ClientResponse से इकाई प्राप्त कर रहा है समस्या को ट्रिगर करने के लिए, लेकिन केवल HTTPS मोड में और मेरे वेब सर्वर के विरुद्ध चल रहा है (google, facebook, etc नहीं)। मैंने को Jetty पर चलाया है और समस्या दोनों के साथ होती है। मैंने अपने subnet पर विभिन्न मशीनों पर वेब सर्वर भी चलाया है और कई मशीनों से परीक्षण इकाई है।



जर्सी HTTPS कक्षाएं

private HostnameVerifier getHostnameVerifier() { 
    HostnameVerifier hv = new HostnameVerifier() { 
    public boolean verify(String arg0, SSLSession arg1) { return true; } 
    }; 
    return hv; 
} 

private SSLContext getSslContext() throws Exception {  
    private final SSLContext sslContext = SSLContext.getInstance("SSL"); 
    sslContext.init(null, new TrustManager[] { new X509TrustManager() { 
     public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } 
     public void checkClientTrusted(X509Certificate[] certs, String authType) {} 
     public void checkServerTrusted(X509Certificate[] certs, String authType) {} 
     } 
    }, new SecureRandom() 
); 
    return sslContext; 
} 



जेट्टी एसएसएल कनेक्टर। यदि मैं HTTP के साथ SelectChannelConnector और इकाई परीक्षण का उपयोग करता हूं तो समस्या दूर हो जाती है।

<Call name="addConnector"> 
    <Arg> 
    <New class="org.mortbay.jetty.security.SslSocketConnector"> 
     <Set name="allowRenegotiate">true</Set> 
     <Set name="Port">8443</Set> 
     <Set name="reuseAddress">true</Set> 
     <Set name="Host">mgmt-int</Set> 
     <Set name="maxIdleTime">30000</Set> 
     <Set name="handshakeTimeout">2000</Set> 
     <Set name="keystore"><SystemProperty name="jetty.home" default="/usr/app/web-app"/>/conf/keystore.jetty</Set> 
     <Set name="password">OBF:1vaaaaaaaaaaaaaaaaaaaa111111111v</Set> 
     <Set name="keyPassword">OBF:1vaaaaaaaaaaaaaaaaaaaa111111111v</Set> 
    </New> 
    </Arg> 
</Call> 
+0

आपका handshakeTimeout अभी तक भी है 2000 एमएमएस पर कम इसे कम से कम 10-15 सेकंड में बदलें। – EJP

+0

मैंने हैंडशेक टाइमआउट को 15000ms तक बढ़ा दिया और समस्या अभी भी होती है। – Karl

+0

क्या आप थ्रेड डंप बना सकते हैं उदा। क्लाइंट पर 'kill -3 pid' के साथ, यह देखने के लिए लटका हुआ है कि यह कहां होता है? –

उत्तर

1

ये किस ओएस पर चल रहे हैं?

बस एक अनुमान है, लेकिन यह धीमी /dev/random कार्यान्वयन से संबंधित हो सकता है (SecureRandom के माध्यम से)।

संबंधित यहाँ चर्चा:

How to solve performance problem with Java SecureRandom?

के बाद से मैं हमेशा एक वेब एप्लिकेशन में JVM मापदंडों पर नियंत्रण नहीं कर सकते, मैं एक समाधान के रूप में इस का उपयोग कर:

static { 
    System.setProperty("java.security.egd", "file:///dev/urandom"); 
} 

डॉन ' टी पता है कि क्या सख्ती से बोलने की सिफारिश की गई है (लेकिन यह मेरे लिए समस्या हल करती है)।

+0

मैंने जेटी को लिनक्स 3.0.0-12-जेनेरिक और 2.6.32.4 9 पर चलाया है।मैंने जावा क्लास को स्थिर ब्लॉक जोड़ा जो जेटी के साथ लोड हो जाता है और इससे मदद नहीं मिली। अपाचे HTTPS क्लाइंट मेरे जेटी सर्वर के साथ ठीक काम करता है, और जर्सी क्लाइंट https google के साथ ठीक काम करता है। यह केवल तभी होता है जब जर्सी क्लाइंट मेरे जेटी सर्वर के खिलाफ चलता है तो समस्या बढ़ जाती है। – Karl

0

थोड़ा अपने trustManager कार्यान्वयन को संशोधित करने की कोशिश कर रहा: इसके अलावा

TrustManager[] trustAllCerts = new TrustManager[] { 
     new X509TrustManager() { 
      public X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 

      public void checkClientTrusted(X509Certificate[] certs, String authType) { 
       // Trust always 
      } 

      public void checkServerTrusted(X509Certificate[] certs, String authType) { 
       // Trust always 
      } 
     } 
    }; 

, मत भूलना अपने getSSLContext के अंत में HttpsURLConnection.setDefaultSocketFactory कॉल करने के लिए() विधि:

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 
+0

मैंने यह कोशिश नहीं की है, लेकिन मैं अपाचे क्लाइंट पर स्विच करना समाप्त कर दिया जो मेरे लिए ठीक काम करता है। – Karl