spring - 使用 RestTemplate 时 "wait"中的许多线程

标签 spring multithreading tomcat spring-boot java-8

当许多请求到达我的网站时,我遇到了速度慢的问题,它开始生成“等待”线程,我已将其余模板设置为 Bean

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder
            .setConnectTimeout(Integer.parseInt(env.getProperty("service.configuration.http.http-request-timeout")))
            .setReadTimeout(Integer.parseInt(env.getProperty("service.configuration.http.http-request-timeout")))
            .requestFactory(clientHttpRequestFactory())
            .build();
}

当我查找产生该问题的进程时,我发现 HttpClient 处于等待状态。

有人知道我该怎么做才能解决这个问题吗?

我正在使用 java8、apache tomcat、spring boot

最佳答案

在我过去的项目中,我使用了这种配置:

@Bean
public RestTemplate restTemplate()
{
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); 
    factory.setHttpClient(httpClient());
    RestTemplate result = new RestTemplate(factory);
    return result;
}
@Bean
public HttpClient httpClient()
{
    CloseableHttpClient httpClient = null;
    //Use a connection pool
    PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager();

    HttpClientBuilder hcb = HttpClientBuilder.create();
    //Close Idle connection after 5 seconds
    pcm.closeIdleConnections(5000, TimeUnit.MILLISECONDS);
    //Specify all the timeouts in milli-seconds
    RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(5000).setSocketTimeout(5000).setConnectTimeout(5000).build();
    hcb.setDefaultRequestConfig(config);
    hcb.setConnectionManager(pcm).setConnectionManagerShared(true);
    // Check if proxy is required to connect to the final resource
    if (proxyEnable)
    {
        //If enabled.... configure it
        BasicCredentialsProvider credentialProvider = new BasicCredentialsProvider();
        AuthScope scope = new AuthScope(hostProxy, portProxy);
        if( StringUtils.hasText(usernameProxy) && StringUtils.hasText(passwordProxy) )
        {

            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(usernameProxy, passwordProxy);
            credentialProvider.setCredentials(scope, credentials);
        }
        hcb.setDefaultCredentialsProvider(credentialProvider).setRoutePlanner(proxyRoutePlanner);
    }
    //Use custom keepalive strategy
    if (cas != null)
    {
        hcb.setKeepAliveStrategy(cas);
    }
    httpClient = hcb.build();
    return httpClient;
}

cas 是以下的实例:

public class WsKeepAliveStrategy implements ConnectionKeepAliveStrategy
    {
        private Long timeout;

        @Override
        public long getKeepAliveDuration(HttpResponse response, HttpContext context)
        {
            return timeout;
        }

        public void setTimeout(Long timeout)
        {
            this.timeout = timeout;
        }

    }

通过这种方式我可以配置httpclient以使用连接池,指定何时关闭空闲连接并指定套接字超时、连接超时、连接请求超时

通过使用此配置,我不再添加任何问题

希望对你有用

安杰洛

关于spring - 使用 RestTemplate 时 "wait"中的许多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46407631/

相关文章:

spring - 使用 Spring Social 进行 Twitter 直播

java - 依赖注入(inject)能帮助我们实现松耦合吗?

c# - 我的 InvokeRequied #2 有什么问题?

C# 多线程应用程序 - 结构?

jsp - Tomcat JSP(2.0) 记录如何停止使用/> 而不是 </tagname> 自动关闭空主体标签

maven - Tomcat 不提供来自 maven-war-plugin 的文件

java - 为每个请求设置 spring 属性

java - 如何在使用 @RunWith(SpringJUnit4ClassRunner.class) 执行任何测试之前 Autowiring Junit 类中的属性

java - 如何在 testNG 类中使用 completableFuture

java - 我们必须将 .class 文件放在 Tomcat 目录中的位置