我使用 
 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()调用.它实际上释放连接回到池.