使 HttpUrlConnection 对远程 REST 端点无限期打开是否合理?
-
23-08-2019 - |
题
我希望优化一个持续运行并通过简单的 REST 风格 HTTP post 频繁调用(平均每秒 > 1 次)外部 API 的流程。我注意到的一件事是,目前,为每个 API 调用创建并关闭 HttpUrlConnection,按照以下结构(为了可读性删除了非必要代码和错误处理)。
//every API call
try {
URL url = new URL("..remote_site..");
conn = (HttpURLConnection) url.openConnection();
setupConnectionOptions(conn); //sets things like timeoout and usecaches false
outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
//send request
} finally {
conn.disconnect();
outputWriter.close();
}
我没有直接处理http协议的丰富经验,但是根据常识/套接字知识,似乎只创建一次连接并重新使用它,并且只重新初始化它会更有效在出现问题时,为了避免每次都进行连接协商,如下所示:
//on startup, or error
private void initializeConnection()
{
URL url = new URL("..remote_site..");
conn = (HttpURLConnection) url.openConnection();
setupConnectionOptions(conn); //sets things like timeoout and usecaches false
}
//per request
try {
outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
//send request
} catch (IOException) {
try conn.disconnect();
initializeConnection();
} finally {
outputWriter.close();
}
//on graceful exit
conn.disconnect();
我的问题是:
- 一般来说,这是一个合理的优化吗(速度提升会很明显)吗?
假设是:
- 我应该重用输出流以及连接吗?
- 仅在出现错误时重新初始化连接是否合理,还是应该在一定数量的请求/时间后重新初始化连接?
解决方案
基本上,是的,而且它节省了大量时间——设置套接字需要花费大量精力,对于 SSL 来说更糟。这就是为什么“keepalive”在过去被实施的原因。这有点违背 REST 理念,但它是一种性能优化。
有一件事是套接字是一种有限的资源。在真正频繁使用的环境中,您最终可能会没有任何套接字可供新连接使用。这是一件坏事。
不隶属于 StackOverflow