Open ichengzi opened 2 years ago
okhttp 是一个java里比较常用的 httpClient, 支持同步、异步请求,socket连接池,资源缓存等。
以下基于3.10讨论。
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.10.0</version> </dependency>
如下,okHttpClient 有几个核心字段
ThreadPoolExecutor.execute()
Dispatcher.maxRequests
Dispatcher.maxRequestsPerHost
synchronized void enqueue(AsyncCall call)
ConnectionPool 实现了socket连接共享,以及失效超时连接的释放,核心是一个线程池
execute()
private static final OkHttpClient _client = new OkHttpClient(); public static String httpGet(String url, Long connectTimeout, Long readTimeout) throws Exception { OkHttpClient client = _client.newBuilder() .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) .readTimeout(readTimeout, TimeUnit.MILLISECONDS) .build(); Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); return response.body().string(); }
假设非单例使用,并且都是同步请求,在默认的配置情况下。
当短期内有大量的请求时1000/min,每次都new一个client,发起一次请求。 那么仅默认的清理线程就有1000个,会引起系统异常。
如果请求时异步的,那么就会有2000个线程, 这个线程消耗情况就更糟糕了。
如果是默认情况配置下, 一个线程线程栈1MB, 2000* 1MB ~~ 2GB, 这个内存消耗更糟糕了。
请求线程, 需要在请求完成后, 1min后才能释放。
清理线程, 需要在socket 5min过期后, 再等1min, 共 5min+ 1min后才能释放。
eg: https://segmentfault.com/a/1190000014498489
// 请求线程, “OkHttp Dispatcher” executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); // 清理线程, "OkHttp ConnectionPoo" private static final Executor executor = new ThreadPoolExecutor(0 /* corePoolSize */, Integer.MAX_VALUE /* maximumPoolSize */, 60L /* keepAliveTime */, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp ConnectionPool", true));
以下基于3.10讨论。
OkHttpClient
如下,okHttpClient 有几个核心字段
Dispatcher
ThreadPoolExecutor.execute()
方法。Dispatcher.maxRequests
Dispatcher.maxRequestsPerHost
来控制同时执行的异步请求,也即线程数量synchronized void enqueue(AsyncCall call)
Dispatcher的enqueue是同步执行的,所以不会出现因并发导致的线程数量失控ConnectionPool
ConnectionPool 实现了socket连接共享,以及失效超时连接的释放,核心是一个线程池
小结
execute()
添加task来控制的。 这里要注意。关于超时配置
使用示例
client非单例情况
假设非单例使用,并且都是同步请求,在默认的配置情况下。
当短期内有大量的请求时1000/min,每次都new一个client,发起一次请求。 那么仅默认的清理线程就有1000个,会引起系统异常。
如果请求时异步的,那么就会有2000个线程, 这个线程消耗情况就更糟糕了。
如果是默认情况配置下, 一个线程线程栈1MB, 2000* 1MB ~~ 2GB, 这个内存消耗更糟糕了。
请求线程, 需要在请求完成后, 1min后才能释放。
清理线程, 需要在socket 5min过期后, 再等1min, 共 5min+ 1min后才能释放。
线程名称