Java连接套接字时有时延迟2分钟?

时间:2017-08-18 18:46:51

标签: java linux sockets kotlin

我对以下谜团感到困惑。在测试我的应用程序时,我经常(可能有25%的时间)在连接SSL套接字时得到两分钟的延迟。我使用的是Java 8,Ubuntu 16.04。当我使用wireshark时,我可以看到没有任何内容通过网络发送到目标服务器。也许可能有其他网络流量,如DNS解析。延迟总是2分钟,不确定度不超过几秒钟。挂起之前的最后一条日志消息是:

DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Connecting socket to redacted:443 with timeout 0

在调试器中暂停验证它是否在PlainSocketImpl类中的套接字连接代码中被阻止:

native void socketConnect(InetAddress address, int port, int timeout)

我很确定我是否注意到这种挂起是否发生在其他应用程序中,我认为这只会影响我的Java程序。我的(Kotlin)代码如下:

import org.apache.http.client.methods.HttpPost
import org.apache.http.config.RegistryBuilder
import org.apache.http.conn.socket.ConnectionSocketFactory
import org.apache.http.conn.ssl.SSLConnectionSocketFactory
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager
import org.apache.http.util.EntityUtils
import java.security.SecureRandom
import javax.net.ssl.*

fun main(args: Array<String>) {
  val client = SSLClient()

  val auth = AuthRequest()
  val ares = auth.post(client)
  val token = ares.value
  println(token)
}

class SSLClient {
    val client : CloseableHttpClient

    init {
        val config = Config
        config.loadCerts()
        val ctx = SSLContext.getInstance("TLSv1.2")
        val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
        kmf.init(config.clientSSLCerts, config.keyPassword.toCharArray())
        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
        tmf.init(config.serverSSLCerts)
        ctx.init(kmf.keyManagers, tmf.trustManagers, SecureRandom())
        val sslsf = SSLConnectionSocketFactory(ctx)

        val r = RegistryBuilder.create<ConnectionSocketFactory>()
                .register("https", sslsf)
                .build()
        val cm = PoolingHttpClientConnectionManager(r)
        client = HttpClients.custom()
                .setConnectionManager(cm)
                .build()
    }

    fun post(endpoint : String) : HttpPost {
        val post = HttpPost(endpoint)
        post.addHeader("Content-Type", "application/xml")
        return post
    }

    fun execute(post : HttpPost, xmlBody : String) : String {
        println(xmlBody)
        post.entity = StringEntity(xmlBody, Charsets.UTF_8)
        client.execute(post).use { response ->
            response.allHeaders.forEach { println(it.toString()) }
            println(response.statusLine.toString())
            if (response.statusLine.statusCode !in 200..299) {
                throw Exception(response.statusLine.toString())
            }
            val entity = response.entity
            if (entity == null || entity.contentLength == 0L) {
                throw Exception("No body content in HTTP response")
            }
            val result = EntityUtils.toString(entity)
            println(result)
            return result
        }
    }
}

我必须提供的最后一条线索是,在调试器中暂停的时间并不计入两分钟。我可以等待五分钟暂停,取消暂停,它仍然需要两分钟。这告诉我它没有等待外部流程完成,因为外部流程会在暂停时间内取得进展。

0 个答案:

没有答案