स्प्रिंग रेस्टेमप्लेट टाइमआउट


125

मैं अपने वेब एप्लिकेशन द्वारा उपयोग की गई बाकी सेवा के लिए कनेक्शन टाइमआउट सेट करना चाहूंगा। मैं अपनी सेवा से बात करने के लिए स्प्रिंग की रेस्टेमप्लेट का उपयोग कर रहा हूं। मैंने कुछ शोध किया है और मैंने नीचे दिए गए xml का उपयोग किया है (अपने आवेदन xml में) जो मुझे लगता है कि टाइमआउट सेट करने के लिए है। मैं स्प्रिंग 3.0 का उपयोग कर रहा हूं।

मैंने यहाँ भी वही समस्या देखी है जोकि TimeTemplate के साथ स्प्रिंग वेबसर्विसेज के लिए टाइमआउट कॉन्फ़िगरेशन है, लेकिन समाधान उतना साफ नहीं लगता , मैं स्प्रिंग कॉन्फ़िगरेशन के माध्यम से टाइमआउट मान सेट करना पसंद करूंगा

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>

      <bean class="org.springframework.http.client.CommonsClientHttpRequestFactory">
        <property name="readTimeout" value="${restURL.connectionTimeout}" />
      </bean>
    </constructor-arg>
</bean>

ऐसा लगता है कि मैंने जो कुछ भी प्राप्त किया है, वह निम्नलिखित है:

नेटवर्क केबल डिस्कनेक्ट किया गया: लगभग 20 सेकंड प्रतीक्षा करता है और अपवाद के बाद रिपोर्ट करता है:

org.springframework.web.client.ResourceAccessExcep tion: I / O त्रुटि: होस्ट करने का कोई मार्ग नहीं: कनेक्ट; नेस्टेड अपवाद java.net.NoRouteToHostException: होस्ट करने का कोई मार्ग नहीं है: कनेक्ट करें

Url गलत है इसलिए 404 बाकी सेवा से लौटा: लगभग 10 सेकंड इंतजार करता है और अपवाद के बाद रिपोर्ट करता है:

org.springframework.web.client.HttpClientErrorException: 404 नहीं मिला

मेरी आवश्यकताओं को कम समय की आवश्यकता होती है इसलिए मुझे इन्हें बदलने में सक्षम होना चाहिए। क्या मैं गलत कर रहा हूँ के रूप में किसी भी विचार?

बहुत धन्यवाद।

जवाबों:


163

के लिए स्प्रिंग बूट> = 1.4

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) 
    {
        return restTemplateBuilder
           .setConnectTimeout(...)
           .setReadTimeout(...)
           .build();
    }
}

के लिए स्प्रिंग बूट <= 1.3

@Configuration
public class AppConfig
{
    @Bean
    @ConfigurationProperties(prefix = "custom.rest.connection")
    public HttpComponentsClientHttpRequestFactory customHttpRequestFactory() 
    {
        return new HttpComponentsClientHttpRequestFactory();
    }

    @Bean
    public RestTemplate customRestTemplate()
    {
        return new RestTemplate(customHttpRequestFactory());
    }
}

तो आपके में application.properties

custom.rest.connection.connection-request-timeout=...
custom.rest.connection.connect-timeout=...
custom.rest.connection.read-timeout=...

यह काम करता है क्योंकि HttpComponentsClientHttpRequestFactoryसार्वजनिक setters है connectionRequestTimeout, connectTimeoutऔर readTimeoutऔर @ConfigurationPropertiesआप के लिए सेट उन्हें।


के लिए स्प्रिंग 4.1 या स्प्रिंग 5 स्प्रिंग बूट के बिना का उपयोग कर @Configurationके बजायXML

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate customRestTemplate()
    {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(...);
        httpRequestFactory.setConnectTimeout(...);
        httpRequestFactory.setReadTimeout(...);

        return new RestTemplate(httpRequestFactory);
    }
}

अच्छा उदाहरण! कृपया, उदाहरण newमें विषम कथन को हटा देंSpring Boot
StasKolodyuk

7
ध्यान दें कि इस कॉन्फ़िगरेशन के बाद, RestTemplate Apache http क्लाइंट (टाइमआउट सेट करने के लिए) का उपयोग करेगा। अपाचे http क्लाइंट कनेक्शन पूल का डिफ़ॉल्ट मैक्सपैरेट थ्रेड्स 5 है, और अधिकतम कुल थ्रेड्स 10 (httpClient-4.5.2) है। हमें खुद को कुछ स्थितियों में सेट करने की आवश्यकता है (जैसे कि हमें कई होस्ट से कनेक्ट करने और अधिक कनेक्शन की आवश्यकता है)।
ब्लूअररो

2
कृपया ध्यान दें connectionRequestTimeoutकि यह विशेषता 4.1.4 से पहले उपलब्ध नहीं है। कृपया
Taoufik Mohdit

मैंने स्प्रिंग बूट> = 1.4 के लिए स्प्रिंग बूट> = 2.1.8 के विन्यास की कोशिश की और मुझे सफलता नहीं मिली। मैंने इस कॉन्फ़िगरेशन को बनाने के लिए इस पोस्ट ( zetcode.com/springboot/resttemplate ) का अनुसरण किया।
ngelo Polotto

@ GivesngeloPolotto आपके द्वारा पोस्ट किया गया लिंक इस समाधान के समान सलाह देता है। लेख कहता है: "वैकल्पिक रूप से, हम नौकरी करने के लिए रेस्टेमप्लेटबर्ल्ट का उपयोग कर सकते हैं।"
डस्टिन.स्कल्त्ज़

76

मुझे आखिरकार यह काम मिल गया।

मुझे लगता है कि इस तथ्य के कारण कि हमारी परियोजना में कॉमन्स-httpclient जार के दो अलग-अलग संस्करण थे, मदद नहीं कर रहे थे। एक बार जब मुझे पता चला कि मैंने पाया है कि आप दो काम कर सकते हैं ...

कोड में आप निम्नलिखित डाल सकते हैं:

HttpComponentsClientHttpRequestFactory rf =
    (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
rf.setReadTimeout(1 * 1000);
rf.setConnectTimeout(1 * 1000);

पहली बार इस कोड को कहा जाता है कि यह उस HttpComponentsClientHttpRequestFactoryवर्ग के लिए टाइमआउट सेट करेगा जिसका उपयोग किया जाता है RestTemplate। इसलिए, बाद में की गई सभी कॉल RestTemplateऊपर बताई गई टाइमआउट सेटिंग्स का उपयोग करेंगी।

या बेहतर विकल्प यह करना है:

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>
        <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
            <property name="readTimeout" value="${application.urlReadTimeout}" />
            <property name="connectTimeout" value="${application.urlConnectionTimeout}" />
        </bean>
    </constructor-arg>
</bean>

जहां मैं RestOperationsअपने कोड में इंटरफ़ेस का उपयोग करता हूं और गुण फ़ाइल से टाइमआउट मान प्राप्त करता हूं।


तो यह इस रेस्ट टेम्प्लेट (जो एक सिंगलटन है) के माध्यम से सभी कॉल के लिए समय समाप्त करता है। क्या आपको पता है कि अनुरोध के अनुसार टाइमआउट को नियंत्रित करना संभव है? (जैसे: एक पोस्ट कॉल के लिए 10 सेकंड और एक कॉल प्राप्त करने के लिए 5 सेकंड)
कोड्सला

@ सरदो। जहाँ मैं अपने कोड में RestOperations इंटरफ़ेस का उपयोग करता हूँ। हमें इसके लिए कोई स्पष्ट इंटरफ़ेस बनाने की आवश्यकता है?
deadend

आपने कहा था कि आप स्प्रिंग 3.0 का उपयोग कर रहे हैं - जिसे मैं भी अटका रहा हूं - लेकिन 3.0 में कोई HttpCompordsClientHttpRequestFactory नहीं है! क्या आपने स्प्रिंग अपडेट किया?
कुटजि

5
उपरोक्त कोड नवीनतम स्प्रिंग में काम नहीं करता है। यह java.lang.ClassCastException: org.springframework.http.client.InterceptingClientHttpRequestFactory cannot be cast to org.springframework.http.client.HttpComponentsClientHttpRequestFactory
ClassCastException

40

यह सवाल स्प्रिंग बूट खोज के लिए पहली कड़ी है, इसलिए, आधिकारिक दस्तावेज में सुझाए गए समाधान को यहां रखना बहुत अच्छा होगा । स्प्रिंग बूट की अपनी सुविधा बीन RestTemplateBuilder है :

@Bean
public RestTemplate restTemplate(
        RestTemplateBuilder restTemplateBuilder) {

    return restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(500))
            .setReadTimeout(Duration.ofSeconds(500))
            .build();
}

RestTemplate उदाहरणों का मैनुअल निर्माण एक संभावित परेशानी भरा दृष्टिकोण है क्योंकि अन्य ऑटो-कॉन्फ़िगर बीन्स को मैन्युअल रूप से बनाए गए इंस्टेंस में इंजेक्ट नहीं किया जा रहा है।


2
खुद की तरह वसंत नवागंतुकों के लिए एक नोट: सिर्फ एक @Configuration में यह चिपका कुछ भी नहीं होगा। इस विधि के लिए आवश्यक है कि आपके पास यह रेस्टेमप्लेट इंजेक्ट किया हुआ स्थान हो, जो इसे रेस्टेमप्लेटएक्सट्रांसपोर्ट के निर्माता के तर्क के रूप में उपयोग करता है, जिसे आप अपने ट्रांसपोर्ट की सूची में जोड़ देंगे, जिसे आप अपने SocksJSient से पास करते हैं।
कुंजी लेट

setConnectTimeoutऔर कुछ कार्यान्वयन setReadTimeoutको हटा दिया गया है
स्काईवेट्स

17

यहाँ मेरे 2 सेंट हैं। कुछ भी नया नहीं है, लेकिन कुछ स्पष्टीकरण, सुधार और नए कोड।

डिफ़ॉल्ट रूप से, RestTemplateअनंत समय समाप्त हो गया है। टाइमआउट दो प्रकार के होते हैं: कनेक्शन टाइमआउट और टाइम आउट पढ़ें। उदाहरण के लिए, मैं सर्वर से जुड़ सकता था लेकिन मैं डेटा नहीं पढ़ सकता था। एप्लिकेशन लटका हुआ था और आपके पास कोई सुराग नहीं है कि क्या चल रहा है।

मैं एनोटेशन का उपयोग करने जा रहा हूं, जो इन दिनों एक्सएमएल पर पसंद किए जाते हैं।

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

        factory.setConnectTimeout(3000);
        factory.setReadTimeout(3000);

        return new RestTemplate(factory);
    }
}

यहां हम SimpleClientHttpRequestFactoryकनेक्शन सेट करने और समय पढ़ने के लिए उपयोग करते हैं। इसके बाद इसे कंस्ट्रक्टर के पास भेज दिया जाता है RestTemplate

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

        return builder
                .setConnectTimeout(Duration.ofMillis(3000))
                .setReadTimeout(Duration.ofMillis(3000))
                .build();
    }
}

दूसरे समाधान में, हम उपयोग करते हैं RestTemplateBuilder। दो तरीकों के मापदंडों पर भी ध्यान दें: वे लेते हैं Duration। ओवरलोड तरीके जो सीधे मिलीसेकंड लेते हैं, अब हटा दिए गए हैं।

स्प्रिंग बूट 2.1.0 और जावा 11 के साथ परीक्षण संपादित करें


आप किस स्प्रिंग और जावा संस्करण का उपयोग कर रहे हैं?
orirab

2
स्प्रिंग बूट 2.1.0 और जावा 11. एक कामकाजी उदाहरण के लिए, आप मेरे ट्यूटोरियल पर एक नज़र डाल सकते हैं: zetcode.com/springboot/resttemplate
Jan Bodnar

मैं इसे उत्तर में जोड़ने का सुझाव देता हूं
orirab

Github.com/spring-projects/spring-boot/blob/master/… देखें । इसे स्प्रिंग बूट 2.1.0 में जोड़ा गया था।
Jan Bodnar

धन्यवाद @JanBodnar, आप ट्यूटोरियल ही हैं जिसने मेरे स्प्रिंग बूट 5.x पर अच्छी तरह से काम किया है
22ngelo Polotto

15

यहाँ टाइमआउट सेट करने का एक बहुत ही सरल तरीका है:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
      new HttpComponentsClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(timeout);
    return clientHttpRequestFactory;
}

0

मेरे पास एक समान परिदृश्य था, लेकिन प्रॉक्सी सेट करने के लिए भी आवश्यक था। ऐसा करने का सबसे सरल तरीका मुझे SimpleClientHttpRequestFactoryप्रॉक्सी को सेट करने में आसानी के लिए विस्तार करना था (गैर-ठेस के लिए अलग-अलग प्रॉक्सी)। यदि आपको प्रॉक्सी की आवश्यकता नहीं है तब भी यह काम करना चाहिए। फिर अपनी विस्तारित कक्षा में मैं स्रोतopenConnection(URL url, Proxy proxy) के समान उपयोग करके विधि को ओवरराइड करता हूं , लेकिन लौटने से पहले सिर्फ टाइमआउट सेट करता हूं ।

@Override
protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
    URLConnection urlConnection = proxy != null ? url.openConnection(proxy) : url.openConnection();
    Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
    urlConnection.setConnectTimeout(5000);
    urlConnection.setReadTimeout(5000);
    return (HttpURLConnection) urlConnection;
}

0

बेंसकैबिया के उत्तर पर विस्तार करने के लिए :

private RestTemplate restCaller = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int connectionTimeout = 5000; // milliseconds
    int socketTimeout = 10000; // milliseconds
    RequestConfig config = RequestConfig.custom()
      .setConnectTimeout(connectionTimeout)
      .setConnectionRequestTimeout(connectionTimeout)
      .setSocketTimeout(socketTimeout)
      .build();
    CloseableHttpClient client = HttpClientBuilder
      .create()
      .setDefaultRequestConfig(config)
      .build();
    return new HttpComponentsClientHttpRequestFactory(client);
}

0
  1. SimpleClientHttpRequestFactory के साथ RestTemplate टाइमआउट प्रोग्रामआउट गुणों को ओवरराइड करने के लिए, हम नीचे दिए गए अनुसार SimpleClientHttpRequestFactory को अनुकूलित कर सकते हैं।

SimpleClientHttpRequestFactory के साथ ओवरराइड टाइमआउट

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    SimpleClientHttpRequestFactory clientHttpRequestFactory
                      = new SimpleClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}
  1. HttpCompordsClientHttpRequestFactory SimpleClientHttpRequestFactory के साथ RestTemplate टाइमआउट सेट करने में मदद करता है, लेकिन यह कार्यक्षमता में बहुत सीमित है और रीयलटाइम अनुप्रयोगों में पर्याप्त साबित नहीं हो सकता है। उत्पादन कोड में, हम HttpCompordsClientHttpRequestFactory का उपयोग करना चाह सकते हैं जो HTTP क्लाइंट लाइब्रेरी के साथ-साथ रेस्टेमप्लेट का समर्थन करते हैं।

HTTPClient अन्य उपयोगी सुविधाएँ प्रदान करता है जैसे कनेक्शन पूल, निष्क्रिय कनेक्शन प्रबंधन आदि।

और पढ़ें: स्प्रिंग रेस्टेमप्लेट + HttpClient कॉन्फ़िगरेशन उदाहरण

HttpCompordsClientHttpRequestFactory के साथ ओवरराइड करें

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
                      = new HttpComponentsClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}

संदर्भ: स्प्रिंग रेस्टेमप्लेट टाइमआउट कॉन्फ़िगरेशन उदाहरण

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.