我使用 Spring来实现以下几点:

在服务器上,我通过XML格式的REST接口接收数据.我想将数据转换成JSON并将其POST到另一台服务器.我的代码(我删除了一些敏感的类名/ URL,以避免雇主的愤怒)看起来像这样:

主/配置类:

package stateservice;

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class App {
    Logger log = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) {
        System.out.println("Start!");
        SpringApplication.run(StateServiceApplication.class,args);
        System.out.println("End!");
    }

    @Bean
    public RestTemplate restTemplate() {
        log.trace("restTemplate()");
        HttpHost proxy = new HttpHost("proxy_url",8080);
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        // Increase max total connection to 200
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(50);

        RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setDefaultRequestConfig(requestConfig);
        httpClientBuilder.setConnectionManager(cm);
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
                httpClientBuilder.build());
        return new RestTemplate(requestFactory);
    }
}

代表RESTful接口的类:

package stateservice;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import foo.bar.XmlData

@RestController
public class StateController {

    private static Logger log = LoggerFactory.getLogger(DataController.class);

    @Autowired
    ForwarderService forwarder;


    @RequestMapping(value = "/data",method = RequestMethod.POST)
    public String postState(@RequestBody XmlData data) {
        forwarder.forward(data);
        return "Done!";
    }
}

最后,货代:

package stateservice;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.httpentity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import foo.bar.Converter;
import foo.bar.XmlData;

@Service
public class ForwarderService {
    private static Logger log = LoggerFactory.getLogger(ForwarderService.class);

    String uri = "forward_uri";

    @Autowired
    RestTemplate restTemplate;

    @Async
    public String forward(XmlData data) {
        log.trace("forward(...) - start");
        String json = Converter.convert(data);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity<String> response = restTemplate.postForEntity(uri,new httpentity<String>(json,headers),String.class);
        // responseEntity.getBody();
        // log.trace(responseEntity.toString());
        log.trace("forward(...) - end");
        return response.getBody();
    }
}

然而,连接管理器很少似乎释放重新使用的连接,此外,系统会在CLOSE_WAIT状态(可以使用netstat看到)中连接.池中的所有连接都被租用,但未被释放,并且一旦CLOSE_WAIT状态的连接数达到ulimit,我会收到’太多的open file’异常

由于代码的多线程性质,我怀疑套接字不能被关闭/连接被释放,因为一些其他线程是无法阻止它们的.

我真的很感激任何帮助或任何提示,你可以帮我解决问题.

解决方法

Apache httpentity有一个技巧 – 释放锁定的连接 – 响应必须被完全消耗和关闭.有关详细信息,请参阅 EntityUtils和 HttpEntity文档:
EntityUtils.consume(response);

从4.3版本开始,当在CloseableHttpResponse上调用#close()方法时,Apache HttpClient会将连接释放回池中.

但是,Spring 4.0版本仅支持Spring Web功能,请参阅HttpComponentsClientHttpResponse.java中的方法#close():

@Override
public void close() {
    // Release underlying connection back to the connection manager
    try {
        try {
            // Attempt to keep connection alive by consuming its remaining content
            EntityUtils.consume(this.httpResponse.getEntity());
        } finally {
            // Paranoia
            this.httpResponse.close();
        }
    }
    catch (IOException ignore) {
    }
}

成功的关键在于“// Paranoia” – 显式.close()调用.它实际上释放连接回到池.

java – PoolingHttpClientConnectionManager不释放连接的更多相关文章

  1. RestTemplate设置超时时间及返回状态码非200处理

    这篇文章主要为大家介绍了RestTemplate设置超时时间及返回状态码非200处理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. 详解RestTemplate 用法

    RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,也有的称之为网络框架,说白了就是Java版本的一个postman,这篇文章主要介绍了详解RestTemplate 用法,需要的朋友可以参考下

  3. RestTemplate的URL请求示例

    这篇文章主要为大家介绍了RestTemplate的URL请求示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. RestTemplate接口调用神器常见用法汇总

    这篇文章主要介绍了RestTemplate接口调用神器常见用法汇总,通过案例代码详细介绍RestTemplate接口调用神器常见用法,需要的朋友可以参考下

  5. Java Http请求方式之RestTemplate常用方法详解

    这篇文章主要为大家介绍了Java Http请求方式之RestTemplate常用方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  6. Java服务调用RestTemplate与HttpClient的使用详解

    无论是微服务还是SOA,都面临着服务间的远程调用,这篇文章主要介绍了服务调用RestTemplate与HttpClient的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. restTemplate超时处理的策略方案

    这篇文章主要为大家介绍了restTemplate超时处理的策略方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. Azkaban的AJAX的RestFul接口调用事例

    azkaban是一个开源的调度工具,可能需要自己修改源码或者自己调用azkaban后台提供的restFul接口进行定制化的开发,在azkaban的官方文档上有接口的详细文档,具体参考:http://azkaban.github.io/azkaban/docs/latest/#ajax-api测试代码如下:1.SSLUtil绕过ssl认证的工具类注意:如果不绕过ssl认证可以自己导入证书,通过如下语

  9. java – 调试RestTemplate发布请求

    我试图在Spring中使用RestTemplatePOST到REST-API.这是我正在使用的代码:我需要正确调试它,看看restTemplate.postForEntity(putUserUrl,String.class)发送到REST服务器的确切JSON是什么;线.我正在使用Eclipse.我已经尝试逐行调试代码.我也尝试将日志级别设置为Debug.遵循注释中给出的步骤后更新下面是我的log4

  10. java – 使用RestTemplate的Spring Security身份验证

    我有2个SpringWeb应用程序,提供2个单独的服务.WebApp1具有使用基于用户身份验证的SpringSecurity实现.现在,WebApp2需要访问WebApp1的服务.通常,我们将使用RestTemplate类向其他Web服务发出请求.我们如何将WebApp2的请求中的认证凭证传递给WebApp1解决方法我处于同样的境地.这里有我的解决方案服务器–弹簧安全配置客户端RestTemplate配置自定义HttpState实现Maven依赖

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部