连接池和文件句柄 [英] Connection pool and File handles

查看:190
本文介绍了连接池和文件句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用Retrofit/OkHttp3处理来自我们Android应用程序的所有网络流量.到目前为止,一切似乎都进行得很顺利.

但是,现在我们的应用程序/进程偶尔会用完文件句柄.

  • Android每个进程最多允许1024个文件句柄
  • OkHttp将为每个异步调用创建一个新线程
  • 以此方式创建的每个线程(根据我们的观察)将负责3个新文件句柄(2个管道和一个套接字).

我们能够准确地对此进行调试,使用.enqueue()的每个分派的异步调用将导致打开文件句柄增加3.

问题是 ConnectionPool 似乎使连接线程保持的时间比实际需要的时间长得多. (这篇文章讨论了五分钟,尽管我在任何地方都没有看到它. )

  • 这意味着,如果您正在快速分派请求,连接池的大小将增加文件句柄的数量也会增加-直到达到1024崩溃.

我已经看到可以使用 Dispatcher.setMaxRequests() (尽管目前尚不清楚这是否真的有效,请参阅这里)-但这仍然不能完全解决打开线程和文件句柄堆积的问题.

我们如何防止OkHttp创建太多文件句柄?

解决方案

我在这里回答自己的问题,以记录我们遇到的这个问题.我们花了一些时间才弄清楚这一点,我认为其他人也可能会遇到这个问题,并且可能对此答案感到高兴.


我们的问题是我们创建了每个请求的OkHttpClient ,因为我们使用了构建器/拦截器API来配置一些按请求的参数,例如HTTP标头或超时

默认情况下,每个OkHttpClient都带有自己的连接池,这当然会炸毁连接/线程/文件句柄的数量,并阻止在池中正确使用.

我们的解决方案

我们通过在单个实例中手动创建全局ConnectionPool,然后将其传递给构建实际OkHttpClientOkHttpClient.Builder对象,解决了该问题.

  • 这仍然允许使用OkHttpClient.Builder
  • 进行每个请求的配置
  • 确保所有OkHttpClient实例仍在使用公共连接池.

我们能够适当地调整全局连接池的大小.

We use Retrofit/OkHttp3 for all network traffic from our Android application. So far everything seems to run quite smoothly.

However, we have now occasionally had our app/process run out of file handles.

  • Android allows for a max of 1024 file handles per process
  • OkHttp will create a new thread for each async call
  • Each thread created this way will (from our observation) be responsible for 3 new file handles (2 pipes and one socket).

We were able to debug this exactly, where each dispached async call using .enqueue() will lead to an increase of open file handles of 3.

The problem is, that the ConnectionPool in OkHttp seems to be keeping the connection threads around for much longer than they are actually needed. (This post talks of five minutes, though I haven't seen this specified anywhere.)

  • That means if you are quickly dispatching request, the connection pool will grow in size, and so will the number of file handles - until you reach 1024 where the app crashes.

I've seen that it is possible to limit the number of parallel calls with Dispatcher.setMaxRequests()(although it seems unclear whether this actually works, see here) - but that still doesn't quite address the issue with the open threads and file handles piling up.

How could we prevent OkHttp from creating too many file handles?

解决方案

I am answering my own question here to document this issue we had. It took us a while to figure this out and I think others might encounter this too and might be glad for this answer.


Our problem was that we created one OkHttpClient per request, as we used it's builder/interceptor API to configure some per-request parameters like HTTP headers or timeouts.

By default each OkHttpClient comes with its own connection pool, which of course blows up the number of connections/threads/file handles and prevents proper reuse in the pool.

Our solution

We solved the problem by manually creating a global ConnectionPool in a singleton, and then passing that to the OkHttpClient.Builder object which build the actual OkHttpClient.

  • This still allows for per-request configuration using the OkHttpClient.Builder
  • Makes sure all OkHttpClient instances are still using a common connection pool.

We were the able to properly size the global connection pool.

这篇关于连接池和文件句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆