Java ssl performance issue in connection with downloads

ぐ巨炮叔叔 提交于 2020-01-01 07:13:11

问题


i'm currently working on a small swift-client and got some hard performance issues by downloading files.

After thousands of checks i localized the problem by downloading files through ssl.

Normal downloads(http) works fine without any problems(or performance issues). But SSL downloads blow up my CPU ... a single core goes up to 100 % load (for a single thread)

i wrote a small testclass without my entire program and can confirm my previous observations.

package testDownload;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class Downloader {

    public Downloader(boolean sslTrigger) throws IOException {

        try {
            this.allowSelfSignCerts();
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        URL url;
        // Http Download
        if (sslTrigger) {
            System.out.println("HTTPS-Mode");
            url                 = new URL("HTTPS LINK");
        } else {
            System.out.println("HTTP-Mode");
            url                 = new URL("HTTP LINK");
        }

        URLConnection conn      = url.openConnection();
        InputStream     input   = conn.getInputStream();
        OutputStream    output  = new FileOutputStream(new File(System.getProperty("user.home")+System.getProperty("file.separator")+"test.dat"));

        ReadableByteChannel inputChannel    = Channels.newChannel(input);
        WritableByteChannel outputChannel   = Channels.newChannel(output);
        System.out.println("start download");
        this.fastChannelCopy(inputChannel, outputChannel);
        inputChannel.close();
        outputChannel.close();
        System.out.println("finish");


    }

    private void fastChannelCopy(ReadableByteChannel src, WritableByteChannel dest) throws IOException {
          ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
            while (src.read(buffer) != -1) {
              buffer.flip();
              dest.write(buffer);
              buffer.compact();
            }
            buffer.flip();
            while (buffer.hasRemaining()) {
              dest.write(buffer);
            }
    }

    private void allowSelfSignCerts() throws NoSuchAlgorithmException, KeyManagementException {
     TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
             public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                 return null;
             }
             public void checkClientTrusted(X509Certificate[] certs, String authType) {
             }
             public void checkServerTrusted(X509Certificate[] certs, String authType) {
             }
         }
     };

     SSLContext sc = SSLContext.getInstance("SSL");
     sc.init(null, trustAllCerts, new java.security.SecureRandom());
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

     HostnameVerifier allHostsValid = new HostnameVerifier() {
         public boolean verify(String hostname, SSLSession session) {
             return true;
         }
     };
     HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    }

}

used java-version

java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

Has anyone an idea for solving this issue?


回答1:


Normal downloads(http) works fine without any problems(or performance issues). But SSL downloads blow up my CPU ... a single core goes up to 100 % load (for a single thread)

This might depend on the cipher client and server agreed on. Very common are AES ciphers. But while AES is fast with special hardware and it terrible slow and CPU bound when done in software. Historically hardware acceleration was not available for Java. But it looks like they've added it in Java 8, even though only for the server JVM.

For more information see AES acceleration for Java and AES-NI intrinsics enabled by default?.



来源:https://stackoverflow.com/questions/31439935/java-ssl-performance-issue-in-connection-with-downloads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!