Tho*_*mas 2 java rest performance jersey java-memory-leaks
我们目前在高效的服务器上遇到了一些问题,因为它消耗的内存过多.其中一个漏洞可能来自球衣客户端.我发现了以下两个问题以及如何:
我从中获得了什么,我应该重用客户端,还可能重用WebTargets?同时建议关闭响应,但是如何使用.request()执行此操作?
代码示例,使用不同的路径每小时调用大约1000次:
public byte[] getDocument(String path) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(config.getPublishHost() + path);
try {
byte[] bytes = target.request().get(byte[].class);
LOGGER.debug("Document size in bytes: " + bytes.length);
return bytes;
} catch (ProcessingException e) {
LOGGER.error(Constants.PROCESSING_ERROR, e);
throw new FailureException(Constants.PROCESSING_ERROR, e);
} catch (WebApplicationException e) {
LOGGER.error(Constants.RESPONSE_ERROR, e);
throw new FailureException(Constants.RESPONSE_ERROR, e);
} finally {
client.close();
}
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是如何正确使用API来防止上述示例的泄漏?
cas*_*lin 10
Client 实例应该重用Client实例是重量级对象,用于管理底层客户端通信基础结构.因此,初始化以及Client实例的处理可能是相当昂贵的操作.
该文档建议仅创建少量Client实例并在可能的情况下重用它们.它还指出,在处置之前Client必须妥善关闭实例以避免资源泄漏.
WebTarget 实例可以重用WebTarget如果对同一路径执行多个请求,则可以重用实例.WebTarget如果他们有一些配置,建议重用实例.
Response 如果您不读取实体,则应关闭实例Response应关闭包含未消耗的实体输入流的实例.这通常仅适用于仅处理响应标头和状态代码的情况,忽略响应实体.有关关闭实例的更多详细信息,请参阅此答案Response
对于您的问题中提到的情况,您希望确保Client实例重用于所有getDocument(String)方法调用.
例如,如果您的应用程序是基于CDI的,Client则在构造bean时创建一个实例,并在销毁之前将其处置.在下面的示例中,Client实例存储在单例bean中:
@Singleton
public class MyBean {
private Client client;
@PostConstruct
public void onCreate() {
this.client = ClientBuilder.newClient();
}
...
@PreDestroy
public void onDestroy() {
this.client.close();
}
}
Run Code Online (Sandbox Code Playgroud)
您不需要(或者可能不能)重用WebTarget实例(每个方法调用请求的路径更改).Response当您将实体读入a时,实例将自动关闭byte[].
连接池可以很好地提高性能.
正如我在旧答案中所提到的,默认情况下,Jersey中的传输层由提供HttpURLConnection.这种支持在泽西岛实施HttpUrlConnectorProvider.如果需要,可以替换默认连接器,并使用连接池以获得更好的性能.
Jersey通过Apache与Apache HTTP Client集成ApacheConnectorProvider.要使用它,请添加以下依赖项:
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<version>2.26</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后Client按如下方式创建您的实例:
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(100);
connectionManager.setDefaultMaxPerRoute(5);
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
clientConfig.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(clientConfig);
Run Code Online (Sandbox Code Playgroud)
有关其他详细信息,请参阅有关连接器的Jersey文档.
| 归档时间: |
|
| 查看次数: |
2316 次 |
| 最近记录: |