- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在使用 Spring 来实现以下目标:
在服务器上,我通过 REST 接口(interface)以 XML 格式接收数据。我想将数据转换为 JSON 并将其发布到另一个服务器。我的代码(我删除了一些敏感的类名/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接口(interface)的类:
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,我就会得到“打开的文件太多”-异常
由于代码的多线程特性,我怀疑无法关闭套接字/释放连接,因为其他一些线程正在阻塞它们。
如果您能给我解决问题的任何帮助或提示,我将不胜感激。
最佳答案
Apache HttpEntity 有一个技巧 - 释放锁定的连接 - 响应必须完全消耗和关闭。见 EntityUtils和 HttpEntity有关详细信息的文档:
EntityUtils.consume(response);
从 4.3 版开始,当在 CloseableHttpResponse 上调用 #close() 方法时,Apache HttpClient 会释放与池的连接。
然而,Spring Web 仅从版本 4.0.0-RELEASE 开始支持此功能,请参阅 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) {
}
}
成功的关键是“//偏执狂”标记的那一行——显式的.close()调用。它实际上将连接释放回池。
关于java - PoolingHttpClientConnectionManager 不释放连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32909653/
我正在使用 Apache PoolingHttpClientConnectionManager 创建连接池。但是我在日志中看到现有的空闲连接未使用,而是创建了一个新连接。下面是代码 PoolingHt
我正在使用 Apache PoolingHttpClientConnectionManager 创建连接池。但是我在日志中看到现有的空闲连接未使用,而是创建了一个新连接。下面是代码 PoolingHt
我有以下声明: PoolingHttpClientConnectionManager manager; Android Studio 返回错误: 错误:(113, 9) 错误:找不到符号类 Pooli
我有一个问题,PoolingHttpClientConnectionManager 的 httpconnection 是什么? 我知道如果我们使用PoolingHttpClientConnection
我的程序包含以下行,此时挂起,我不太清楚为什么。 PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClien
我正在使用 Spring 来实现以下目标: 在服务器上,我通过 REST 接口(interface)以 XML 格式接收数据。我想将数据转换为 JSON 并将其发布到另一个服务器。我的代码(我删除了一
所以我有一个 Spring 应用程序,我使用 PoolingHttpClientConnectionManager 为从此应用程序发出的所有 http 请求创建连接池。我只有一台主机可以调用,这意味着
org.apache.http.impl.conn.PoolingHttpClientConnectionManagerorg.apache.http.impl.nio.conn.PoolingNHt
我正在使用 httpClient 4.3.6,CloseableHttpClient 由 PoolingHttpClientConnectionManager 提供服务。 我当前的设置包括 200 个
这是我的使用方法- private static final PoolingHttpClientConnectionManager connPool; static { connPoo
我们想在 Glassfish 3.1 Open 的 EJB 容器中使用 HttpClient源版本。 在HttpClient documentation我们看到以下关于 BasicHttpClient
PoolingHttpClientConnectionManager 和 PoolingClientConnectionManager 之间有什么区别。为什么 PoolingClientConnect
我正在处理的 Web 服务需要将传入的 json 数据发送到另一个服务的 REST 接口(interface)。为此,我编写了一个依赖于 Apache 项目的 HttpClient-lib 的小转发器
我正在尝试使用我正在使用的客户端代码在服务器上使用连接池(已配置 Https SSL)PoolingHttpClientConnectionManager 和我有一个带连接池的工作代码,但我想知道我的
我正在编写一个需要运行许多并行 http 请求的服务。它也将部署在自动扩展环境中,但我希望从每个服务实例中获得尽可能多的性能。 我看到这篇文章How to determine the maximum
有人可以向我解释一下 setMaxPerRoute(max) 和 setMaxTotal(max) 在引用 HttpComponents PoolingHttpClientConnectionMana
所以我似乎在使用 PoolingHttpClientConnectionManager 时遇到与 DNS 主机名解析缓存相关的问题。我有一个可以调用外部服务的 api。此服务使用 Akamai 边缘缓
我们使用 Spring Boot 2 与 Actuator 和 Prometheus 来显示 Grafana 仪表板。我想添加 Apache Http Client PoolingHttpClient
我知道如何模拟 default HttpClient ,但是我如何模拟使用 PoolingHttpClientConnectionManager 创建的最新(v4.4)HttpClient与莫基托?
所以我最近在尝试使用 IDE 运行我们现有的测试套件时开始面临 TestNGException。最近我的意思是更新 intelliJ 和依赖项以尝试在最新版本上工作。失败的代码和堆栈跟踪如下 - 代码
我是一名优秀的程序员,十分优秀!