简体   繁体   English

对于同时发起出站调用的请求,有一个 HTTP 连接池和一个线程执行器池是否有意义?

[英]Does it make sense to have an HTTP connection pool and a thread executor pool for requests that originate the outbound calls at the same time?

I am working on a RESTful service that uses a fixed executor pool for outbound call requests like:我正在开发一个 RESTful 服务,该服务使用固定的执行程序池来处理出站调用请求,例如:

return CompletableFuture
    .supplyAsync(() -> {
      try {
        return restTemplate.exchange(uri, method, request, responseType, new Object[0]);
      } catch (IOException | URISyntaxException e) {
        e.printStackTrace();
      }
      return null;
    }, pool); //This is a thread pool executor with a fixed size
}

This restTemplate also has a fixed connection pool specified (with a lot of boilerplate I will not include) through a PoolingHttpClientConnectionManager .这个 restTemplate 也有一个通过PoolingHttpClientConnectionManager指定的固定连接池(有很多样板我不会包括在内)。

I am interpreting this as unnecessarily offloading the outbound calls from the originating threads, which are blocked by the connection threads and do not perform any other tasks in the meantime.我将此解释为不必要地卸载来自原始线程的出站调用,这些线程被连接线程阻止并且在此期间不执行任何其他任务。 But I was unable to convince the author of this who insists on performance gains when auxiliary tasks like logging etc. are involved (which I think should be the tasks that are offloaded here)但是我无法说服这个坚持在涉及日志记录等辅助任务时提高性能的作者(我认为应该是这里卸载的任务)

What am I missing here?我在这里缺少什么?

In isolation it does seem redundant, but stepping back, it can make sense.孤立地看,这似乎是多余的,但退一步说,它是有道理的。

The main reason is that restTemplate.xx() are blocking calls.主要原因是restTemplate.xx()正在阻塞调用。 If you use them, you have to wait for the (http) response to proceed to the next instruction.如果使用它们,则必须等待 (http) 响应才能进行下一条指令。

Fire and forget火与遗忘

Now suppose this HTTP call is a "fire and forget" call, you just send data out, and you discard (or do not need) the call's response to forge your own response.现在假设这个 HTTP 调用是一个“即发即弃”的调用,您只需将数据发送出去,然后丢弃(或不需要)调用的响应来伪造您自己的响应。 Then threading is a great way to send your response earlier.那么线程是一种提前发送响应的好方法。

Independant work to do独立工作

Suppose the call is important, you need its response, but you have some work to do in the meantime.假设呼叫很重要,您需要它的响应,但在此期间您还有一些工作要做。 Maybe you have a DB request to fetch.也许您有一个要获取的数据库请求。 Maybe a file to read.也许是一个要阅读的文件。 Maybe another HTTP call to make, or just about anything that does not require the response of the HTTP call yet.也许要进行另一个 HTTP 调用,或者几乎不需要 HTTP 调用响应的任何内容。 You can start working on that while your thread is waiting for the HTTP response.您可以在线程等待 HTTP 响应时开始处理。 That's a boost.这是一个提升。

Chaining work连锁工作

Suppose you are calling this one service, and with the result of this one call, you have to make two other calls, one of them need to perform a third call, and the result of all that is needed to perform a fourth call.假设您正在调用这一项服务,并且根据这一次调用的结果,您必须进行另外两次调用,其中一次需要执行第三次调用,以及执行第四次调用所需的所有结果。

CompletableFutures (or other reactive programming tools) are designed for that. CompletableFutures(或其他反应式编程工具)就是为此而设计的。 Anything that can run concurrently will, and dependencies are set in a declarative way that hides it.任何可以并发运行的东西都会,并且依赖项以一种隐藏它的声明方式设置。 It's great, and as performant as can be.它很棒,而且性能非常好。

Configuration conflicts配置冲突

The rest template is based on some HTTP client, that pools connections.其余模板基于一些 HTTP 客户端,它汇集连接。 Connection pools have all kind of tuning parameters, eg total number of outbound connections/sockets, sockets per host, or per HTTP proxy, or what not.连接池具有各种调整参数,例如出站连接/套接字的总数、每个主机或每个 HTTP 代理的套接字,或其他。

Now suppose the HTTP call you're about to make, for some reason, is rate limited (external API technical or contractual restrictions), and the HTTP pool is not aware or configurable for that.现在假设您将要进行的 HTTP 调用由于某种原因受到速率限制(外部 API 技术或合同限制),并且 HTTP 池不知道或无法为此进行配置。 Then using a thread pool as a controler for the number of concurrent requests can be the simplest way.那么使用线程池作为并发请求数量的控制器可能是最简单的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM