性能如何在JAVA中加速tls协商?
有一个私有的web服务器(支持https),我需要经常在上面读取/设置一些信息。我编写了一些java代码来自动完成它。当我使用Chrome访问它时,第一次连接很慢(可能5秒),但连续连接很快(大约1秒)。对于我的java代码,每次都很慢。我知道问题是在我的代码的每个连接中都会执行完整的TLS握手。我的问题是,Chrome做了什么来加快它,我如何在我的代码中模拟它?以下是我的代码的一部分:
class MyTrust implements X509TrustManager{
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {return null; }
}
在建立连接的另一类中:
URLConnection conn = (HttpsURLConnection) url.openConnection();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new MyTrust() }, new java.security.SecureRandom());
((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
我正在读Java Secure Socket Extension (JSSE) Reference Guide,但觉得很难理解。是SessinID还是Principal起作用?谁能给我一些提示吗
# 1 楼答案
java代码每次都会建立连接,因此每次都会执行TLS握手
但是浏览器(如Chrome)将尝试保持连接活动(通过在请求中添加
Connection:Keep-Alive
头),如果服务器接受保持活动连接(通过在响应中返回Connection:Keep-Alive
头),大多数服务器都会这样做,浏览器将尝试在正在进行的请求中使用相同的连接,因此,不需要每次都执行TLS握手对于java代码,可以将连接存储在池中,并重用它。您可以检查Apache HttpComponents,它支持http连接池
根据评论编辑:
因为真正的问题是SSL/TLS会话重用不起作用。我怀疑这是由于误用JSSE造成的。必须在每个连接上使用相同的SSLContext才能启用会话重用。此外,由于连接上的一些错误操作(例如读取流的末尾),会话可能会被丢弃。这里列出了一些详细信息:How to enable client TLS session reuse in Java