在进行同步调用时,许多ReaderRunnable线程仍在运行

时间:2018-03-20 20:52:02

标签: java okhttp

使用OkHttpClient 3.6.0

我有一个100k通知流,用于相同的SSL证书和主机发送给APNS。应用程序读取此流,对它们进行排队并使用具有800个线程的执行程序服务进行同步调用,如下所示:

client.newCall(request).execute()

在过去的几天里,我发现我们正在创建大量的连接(因此有很多ReaderRunnable线程)。我知道这一点,通过查看连接数很高时的连接数和相应的堆栈跟踪。我看到许多来自ReaderRunnable的OkHttp api.push.apple.com个线程。

"OkHttp api.push.apple.com" #84247 daemon prio=5 os_prio=0 tid=0x00002b3a7c022800 nid=0xefd3 runnable [0x00002b29f5e1e000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    - locked <0x00002b34f69a7728> (a java.lang.Object)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
    - locked <0x00002b34f69a7f48> (a sun.security.ssl.AppInputStream)
    at okio.Okio$2.read(Okio.java:138)
    at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
    at okio.RealBufferedSource.request(RealBufferedSource.java:66)
    at okio.RealBufferedSource.require(RealBufferedSource.java:59)
    at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.java:95)
    at okhttp3.internal.http2.Http2Connection$ReaderRunnable.execute(Http2Connection.java:566)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.lang.Thread.run(Thread.java:745)



2018-03-20 19:58:02 - OkHttpClient Connection Pool Count is 336
2018-03-20 19:59:02 - OkHttpClient Connection Pool Count is 12182
2018-03-20 20:00:07 - OkHttpClient Connection Pool Count is 17081
2018-03-20 20:01:02 - OkHttpClient Connection Pool Count is 19700
2018-03-20 20:02:01 - OkHttpClient Connection Pool Count is 10 

这导致我们有时会达到进程和应用程序OOM的线程限制。

问题

这里有两个问题:

  1. 为什么我们要建立这么多联系?我认为这是b / c APNS返回SETTINGS_MAX_CONCURRENT_STREAMS = 1.是否可以进行一些帧记录确认? [更新:我可以打印帧日志,但不能打印实际帧本身或设置。]

  2. 由于我只使用800个线程并发出同步请求,即使我们最终为每个请求建立一个新连接,为什么池中的连接数超过800或(810 w / idle buffer)任何给定的时间? 这是我在配置客户端时设置连接超时和连接池的方法:

    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.connectTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS);
    builder.connectionPool(new ConnectionPool(HTTP_CLIENT_MAX_CONNECTIONS, 10, TimeUnit.MINUTES));
    

0 个答案:

没有答案