对okhttp参数的一些思考
背景
项目中使用OkHttp访问三方服务
参数
创建okhttp客户端类的时候需要设置一些参数,有些可能是坑,仅供参考:
client = new OkHttpClient.Builder() .dispatcher(new Dispatcher(executorService)) .connectionPool(new ConnectionPool(maxIdleConnections, keepAliveDurationMills, TimeUnit.MILLISECONDS)) .readTimeout(readTimeoutMills, TimeUnit.MILLISECONDS) .connectTimeout(connectTimeoutMills, TimeUnit.MILLISECONDS) .writeTimeout(writeTimeoutMills, TimeUnit.MILLISECONDS) .protocols(Util.immutableList(Protocol.HTTP_1_1)) .connectionSpecs(Arrays.asList(TLS_SPEC, ConnectionSpec.CLEARTEXT)) .build(); client.dispatcher().setMaxRequests(maxRequests); client.dispatcher().setMaxRequestsPerHost(maxRequestsPerHost); |
||
参数 |
意义 |
推荐值及原则 |
executorService |
内部执行http请求的实际线程池 |
默认executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); 没有常驻线程,性能低,线程没有限制上限。 |
maxIdleConnections |
连接池大小,指单个okhttpclient实例所有连接的连接池。 |
默认:5,值的设置与业务请求量有关,如果请求三方的tps是200,建议这个值设置在200左右。 |
keepAliveDurationMills |
连接池中连接的最大时长 |
默认5分钟,依据业务场景来确定有效时间,如果不确定,那就保持5分钟 |
connectTimeoutMills |
连接的最大超时时间 |
默认10秒 |
readTimeoutMills |
读超时 |
默认10秒,如果是流式读,那建议设置长一点时间。 With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. |
writeTimeoutMills |
写超时 |
默认10秒,如果是流式写,那建议设置长一点时间 |
maxRequests |
当前okhttpclient实例最大的并发请求数 |
默认:64,默认的64一般满足不了业务需要。这个值一般要大于maxRequestPerHost,如果这个值小于maxRequestPerHost会导致,请求单个主机的并发不可能超过maxRequest. |
maxRequestPerHost |
单个主机最大请求并发数,这里的主机指被请求方主机,一般可以理解对调用方有限流作用。注意:websocket请求不受这个限制。 |
默认:4,一般建议与maxRequest保持一致。 这个值设置,有如下几个场景考虑: (1)如果被调用方的并发能力只能支持200,那这个值最好不要超过200,否则对调用方有压力; (2)如果当前okhttpclient实例只对一个调用方发起调用,那这个值与maxRequests保持一致; (3)如果当前okhttpclient实例在一个事务中对n个调用方发起调用,n * maxReuestPerHost要接近maxRequest |
maxRequests和maxReuestsPerHost值的设置与executorService线程池的设置有关联,请注意。maxRequests和maxRequestPerHost是okhttp内部维持的请求队列,而executorservice是实际发送请求的线程。如果maxRequests和maxReuestPerHost设置太大,executorService会因为线程太少而阻塞发送。