Nat*_*H06 3 java scala apache-commons-httpclient apache-httpclient-4.x
我正在使用 Apache Http Client 4.5.3,目前正在重构一些代码。
目前我有一个单例 Util,它有几个方法,它们的职责是使用 get、posts、patch 等来访问 API。以前,我们一直使用 anHttpClientBuilder为CloseableHttpClient每个方法的每次调用构造一个对象。粗略地说,单例的架构是这样的:
import com.google.gson.Gson
import org.apache.http.client.methods.{HttpGet, HttpPost}
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.{CloseableHttpClient, HttpClientBuilder}
import org.apache.http.util.EntityUtils
import org.json4s.DefaultFormats
import org.json4s.jackson.JsonMethods.parse
object ApiCallerUtil {
case class StoreableObj(name:String, id:Long)
case class ResponseKey(key:Long)
def getKeyCall(param:String): ResponseKey = {
implicit val formats = DefaultFormats
val get = new HttpGet("http://wwww.someUrl.com/api/?value=" + param)
val client:CloseableHttpClient = HttpClientBuilder.create().build()
val response = client.execute(get)
try {
val entity = response.getEntity
val entityStr = EntityUtils.toString(entity)
parse(entityStr).extract[ResponseKey]
} finally {
response.close()
client.close()
}
}
def postNewObjCall(param:String, i:Long): Boolean = {
val post = new HttpPost(("http://wwww.someUrl.com/api/createNewObj"))
val client = HttpClientBuilder.create().build()
post.setHeader("Content-type", "application/json")
val pollAsJson = new Gson().toJson(StoreableObj(param, i))
post.setEntity(new StringEntity(pollAsJson))
val response = client.execute(post)
try {
if (response.getStatusLine.getStatusCode < 300) true else false
} finally {
response.close()
client.close()
}
}
//... and so on
}
Run Code Online (Sandbox Code Playgroud)
关于如何使用它的注意事项 - 我们的系统中有许多类使用这个 Singleton Util 来调用 API。这个 Singleton 将经历短时间的大量使用,其中几个类将频繁地调用相同的调用(在几分钟内高达 @1000 次),以及在很长一段时间内被多次调用的时期(每小时一次或两次),或者一次几个小时内根本不这样做。此外,它命中的所有 URL 都将以相同的 URL 开头(例如www.someUrl.com/api/)
但是我想知道在将val client = HttpClientBuilder.create().build调用一次作为对象内可访问变量的私有 val 的情况下实现它是否有意义。这样它只在对象实例化时创建一次。这是我暂停的地方,Apache 文档确实说了这两件事:
1.2.1. [Closeable] HttpClient 实现应该是线程安全的。建议将此类的同一实例重用于多个请求执行。
1.2.2. 当不再需要 [Closeable]HttpClient 实例并且即将超出范围时,关闭其连接管理器以确保管理器保持活动的所有连接都关闭并释放这些连接分配的系统资源非常重要。
我已经阅读了大部分文档,但对以下问题没有可靠的答案:
将 CloseableHttpClient 实例作为私有全局变量是否有任何风险?我担心某些东西可能会被关闭,如果它是陈旧的,我必须在一段时间后重新实例化它,或者在大量使用的情况下,它会产生太多的瓶颈。根据上面的#1.2.2,变量“永远”不会超出范围,因为它是一个单例对象。但是由于我只是在构建客户端并在运行时将HttpRequest对象传递给它,而不是单独将它连接到请求之外的 API,所以这似乎无关紧要。
由于如何使用这个ApiCallerUtilSingleton的性质,使用它们的HttpClientConnectionManageror是否明智。PoolingHttpClientConnectionManager保持稳定的连接www.someUrl.com/api/?性能提升是否值得?到目前为止,当前的实现似乎没有任何严重的性能缺陷。
感谢您的任何反馈!
没有(基于我 15 年以上的 HttpClient 经验)。
这实际上取决于各种因素(TLS 会话握手的开销等)。我想人们真的希望确保通过持久连接执行一系列相关请求。在长时间的不活动期间,人们可能希望从连接池中驱逐所有空闲连接。这有一个额外的好处,即减少遇到陈旧(半封闭)连接问题的机会。
| 归档时间: |
|
| 查看次数: |
3485 次 |
| 最近记录: |