当前位置: 首页 > 知识库问答 >
问题:

如何控制okHttpClient连接大小?

端木兴国
2023-03-14
    OkHttpClient okHttpClient = new OkHttpClient().setConnectTimeout(TIMEOUT);
    ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS,
                                                       KEEP_ALIVE_DURATION_MS);
    okHttpClient.set(connectionPool);

    @RequireArgsConstructor
    public HttpEngineCallable implements Callable<IHttpResponse>
    {
      private final String url;

      public IHttpResponse call () throws Exception 
      {
         try
        {
           Request request = Request.Builder().url(url).build();
           Call call = okHttpClient.newCall(request);
           Response rawResponse = call.execute();
           return new OkHttpResponse(rawResponse);
        }
        catch (Exception e)
        {
           throw new IllegalStateException(e);
        }
    }  

    private final Function<IHttpResponse, T> httpResponseParser = new Function<IHttpResponse, T>()
    {
        @Nullable
        @Override
        public T apply(@Nullable IHttpResponse httpResponse)
        {
            if(httpResponse == null)
            {
               return null;
            }

            InputStream stream = httpResponse.getBody();
            JsonParser parser = null;
            T result = null;

            try
            {
               parser = jsonFactory.createParser(stream);
               result = strategy.parseData(parser);
            }
            catch (Exception e)
            {
               log.error("Unable to convert {} with {}.", stream, strategy, e);
            }
            finally
            {
               IOUtils.closeQuietly(parser);
               IOUtils.closeQuietly(stream);
            } 

          return result;
        }
     };

     Future<T> future = executorService.submit(new HttpEngineCallable(url));
     Future<V> finalFuture = Futures.transform(future, httpResponseParser, executorService);

     T result = timeoutExecutorService.submit(new Runnable() 
     {
        try
        { 
          T result = finalFuture.get(CLIENT_TIMEOUT, TIMEUNIT)
          if (result == null)
          { 
            notify onFailure listeners
          }
          else
          {
            notify onSuccess Listeners
          }
        }
        catch(Exception ex)
        {
          notify onFailure listeners
        }
     } 

所以我有几个关于这个实现的问题:

  1. 我的CLIENT_TIMEOUT比OkHttp ConnectTimeout短。如果我的finalfuture.get(CLINT_TIMEOUT,TIMEUNIT)抛出超时异常,解析器函数中的finally block还会执行吗?我指望它能关闭我的联系。
  2. 如何限制连接池的大小?如果连接超出限制,有没有办法自动回收最旧的连接?

共有1个答案

乐正瑞
2023-03-14

我们有一个类似的问题,太多打开的文件描述符使我们的应用程序崩溃。

问题是我们为每个请求创建了一个OkHttpClient。默认情况下,每个OkHttpClient都有自己的连接池,这当然会增加连接/线程/文件句柄的数量,并阻止池中的适当重用。

我们解决了这个问题,方法是在单例中手动创建一个全局ConnectionPool,然后将其传递给构建实际OKHttpClient的OKHttpClient的OKHttpClient对象

...
builder.connectionPool(GLOBAL_CONNECTION_POOL);
OkHttpClient client = builder.build();
...
 类似资料:
  • 是否可以使用OkHttpClient限制活动连接的数量?所以,如果达到限制,就不会选择和建立新的连接? 我的应用程序同时启动多个连接。

  • 我目前正在使用okhttp 3.10.0,我最近才发现,为每个新请求创建一个新的客户端对每个拥有自己连接池的客户端都是有害的。 我在servlet中使用okhttp。我现在要做的就是在每个servlet中声明一个静态客户机,并在init()方法中初始化它 这里是最大空闲连接的配置,我将其设置为20,空闲超时设置为5分钟。 1)实际的池大小是多少,即池将具有的最大连接(通过代码查看,我发现它可能是I

  • 问题内容: 我想使用OkHttpClient加载URL,如果给定URL的网站以pdf内容类型响应,我将继续下载PDF,否则我想忽略响应。 我的问题是,我是否需要做一些特殊的事情来关闭请求/响应,或者如果我选择不读取响应字节流,是否需要做任何事情来表明我将不使用响应?如果没有,OkHttpClient何时关闭连接? 问题答案: 调用将释放响应所拥有的所有资源。连接池将使连接保持打开状态,但是如果未使

  • 我想使用OkHttpClient加载一个url,如果给定url的网站以pdf内容类型响应,我将继续下载pdf,否则我想忽略响应。 我的问题是,我是否需要做任何特别的事情来关闭请求/响应,或者我是否需要做任何事情来表明如果我选择不读取响应字流,我将不会使用响应?如果没有,OkHttpClient何时关闭连接?

  • 很容易说它是重复的,但它不是。 我读过许多关于如何在中设置连接超时的帖子,但是这些帖子已经有4-7年的历史了,我认为我们都需要更新这个主题,因为这些方法已经不被推荐或者不再存在了。 所以问题是,当我等待服务器的响应时,如何设置连接超时?

  • 服务端连接控制 限制服务器端接受的连接不能超过 10 个 1: <dubbo:provider protocol="dubbo" accepts="10" /> 或 <dubbo:protocol name="dubbo" accepts="10" /> 客户端连接控制 限制客户端服务使用连接不能超过 10 个 2: <dubbo:reference interface="com.foo.Ba