java 缓存 cachedKeyStore cachedSSLContext ?

分析只缓存 SSLContext 的情况优点:从功能角度来说,缓存SSLContext可以直接用于构建HttpClient。因为SSLContext已经包含了信任管理(通过TrustManager初始化)等相关信息,后续在循环调用时,直接使用缓存的SSLContext来构建HttpClient可以避免重复的KeyStore加载、TrustManagerFactory初始化等操作,能够提高性能。例如:

if (!isInitialized) {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    FileInputStream fis = new FileInputStream(SystemVar.tomcatJKS);
    keyStore.load(fis, SystemVar.tomcatJKSPassword.toCharArray());
    fis.close();
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagers, new java.security.SecureRandom());
    // 只缓存SSLContext
    cachedSSLContext = sslContext;
    isInitialized = true;
} else {
    HttpClient client = HttpClient.newBuilder()
           .version(HttpClient.Version.HTTP_2)
           .sslContext(cachedSSLContext)
           .build();
    java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
           .uri(URI.create(urlStr))
           .timeout(java.time.Duration.ofSeconds(10))
           .GET()
           .build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    jsonString = response.body();
}

 潜在问题

  • 如果在某些情况下需要直接访问KeyStore(虽然在当前checkOtherPolicyHttpRequest方法展示的逻辑中可能不需要),例如要检查证书的有效期、获取证书中的某些特定信息等操作,没有缓存KeyStore会导致需要重新加载和初始化KeyStore,增加额外的开销。

分析只缓存 KeyStore 的情况优点KeyStore是存储证书和密钥的仓库,缓存它可以在后续需要时灵活地进行各种操作。例如,如果要更新SSLContext的信任配置(如添加新的信任证书或者更新证书密码等操作),有缓存的KeyStore可以方便地重新初始化TrustManagerFactorySSLContext。示例如下:

if (!isInitialized) {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    FileInputStream fis = new FileInputStream(SystemVar.tomcatJKS);
    keyStore.load(fis, SystemVar.tomcatJKSPassword.toCharArray());
    fis.close();
    // 只缓存KeyStore
    cachedKeyStore = keyStore;
    isInitialized = true;
} else {
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(cachedKeyStore);
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagers, new java.security.SecureRandom());
    HttpClient client = HttpClient.newBuilder()
           .version(HttpClient.Version.HTTP_2)
           .sslContext(sslContext)
           .build();
    java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
           .uri(URI.create(urlStr))
           .timeout(java.time.Duration.ofSeconds(10))
           .GET()
           .build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    jsonString = response.body();
}

 

  • 潜在问题
    • 每次循环调用时,还是需要重新初始化TrustManagerFactorySSLContext,相比于直接缓存SSLContext,性能提升可能没有那么显著,因为TrustManagerFactory的初始化和SSLContext的构建过程也涉及一些计算和对象创建的开销。

结论

  • 从性能优化的角度,特别是对于当前checkOtherPolicyHttpRequest方法主要关注的快速构建HttpClient进行请求的功能,缓存SSLContext可能就足够了。但从代码的灵活性和潜在的其他功能扩展角度(如证书信息检查、更新信任配置等),缓存KeyStore也有其价值。如果确定在后续的代码扩展和维护过程中不会涉及直接对KeyStore的操作,那么只缓存SSLContext是可以的;否则,考虑同时缓存或者只缓存KeyStore以保持代码的灵活性。
posted @ 2024-12-17 08:49  锐洋智能  阅读(1)  评论(0编辑  收藏  举报