Java ssl性能问题与下载有关 [英] Java ssl performance issue in connection with downloads

查看:139
本文介绍了Java ssl性能问题与下载有关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用一个小型的swift客户端,并通过下载文件来获得一些难度的性能问题。

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

经过数千次检查,我通过下载文件来本地化了问题通过ssl。

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

正常下载(http)工作正常,没有任何问题(或性能问题)。
但是SSL下载令我的CPU ... ...一个单一的核心达到100%的负载(单线程)

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);
    }

}

使用java-version

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?

推荐答案


正常下载http)工作正常,没有任何问题(或性能问题)。但是,SSL下载会令我的CPU发生爆炸...一个核心升级到100%负载(单线程)

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)

这可能依赖于密码客户端和服务器同意。非常常见的是AES密码。但是AES虽然采用特殊的硬件,但在软件中完成时可能会造成严重的缓慢和CPU限制。以前硬件加速不适用于Java。但是看起来他们已经在Java 8中添加了它,即使只是用于服务器JVM。

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.

有关更多信息,请参阅 AES加速Java

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

这篇关于Java ssl性能问题与下载有关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆