Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
服务响应时间慢:Java SecureRandom&/开发/随机_Java_Tomcat_Random_Aes_Strace - Fatal编程技术网

服务响应时间慢:Java SecureRandom&/开发/随机

服务响应时间慢:Java SecureRandom&/开发/随机,java,tomcat,random,aes,strace,Java,Tomcat,Random,Aes,Strace,我试图调试部署在Tomcat上的应用程序提供的一些缓慢响应。 现在我主要关注的是SecureRandom和/dev/random(其他一些可能的原因已经调查并排除)。 模式如下: 第一次调用在Tomcat重新启动后正好30.0xy秒(即使请求在启动后4分钟到达) 后来,有些通话只需15.0pq秒(我无法确定具体模式,pq是TP99中所用时间的近似值) 服务调用涉及加密和解密(AES/ECB/PKCS5P) SecureRandom初始化/重新填充是否可能导致这种情况 (尽管如此,catali

我试图调试部署在Tomcat上的应用程序提供的一些缓慢响应。 现在我主要关注的是
SecureRandom
/dev/random
(其他一些可能的原因已经调查并排除)。 模式如下:

  • 第一次调用在Tomcat重新启动后正好30.0xy秒(即使请求在启动后4分钟到达)
  • 后来,有些通话只需15.0pq秒(我无法确定具体模式,pq是TP99中所用时间的近似值)
服务调用涉及加密和解密(AES/ECB/PKCS5P)

SecureRandom初始化/重新填充是否可能导致这种情况

(尽管如此,catalina.log中有一个日志说,
“使用[SHA1PRNG]为会话ID生成创建SecureRandom实例需要[28760]毫秒。”

另外,为了检查是否正在使用
/dev/random
/dev/uradom
,我使用了来自的测试。令我惊讶的是,我没有看到他们中的任何一个读到的内容,这与链接问题中的情况不同。 以下是
strace
日志中的最后几行:

3561  lstat("/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jsse.jar", {st_mode=S_IFREG|0644, st_size=258525, ...}) = 0
3561  open("/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jsse.jar", O_RDONLY) = 6
3561  stat("/dev/random", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
3561  stat("/dev/urandom", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
3561  open("/dev/random", O_RDONLY)     = 7
3561  open("/dev/urandom", O_RDONLY)    = 8
3561  unlink("/tmp/hsperfdata_xxxx/3560") = 0
那么,什么是用来播种的呢

仅供参考,java版本


我无法检查您的OpenJDK具体版本,但我可以检查

用于获取种子字节

public byte[] engineGenerateSeed(int numBytes) {
    byte[] b = new byte[numBytes];
    SeedGenerator.generateSeed(b);
    return b;
}
SeedGenerator从中获取
seedSource
(字符串)

SunEntries
首先尝试从系统属性
java.security.egd
获取源,如果未找到,则尝试从
java.security
属性文件获取属性
securerandom.source
,如果未找到属性,则返回空字符串

// name of the *System* property, takes precedence over PROP_RNDSOURCE
private final static String PROP_EGD = "java.security.egd";
// name of the *Security* property
private final static String PROP_RNDSOURCE = "securerandom.source";

final static String URL_DEV_RANDOM = "file:/dev/random";
final static String URL_DEV_URANDOM = "file:/dev/urandom";

private static final String seedSource;

static {
    seedSource = AccessController.doPrivileged(
            new PrivilegedAction<String>() {

        public String run() {
            String egdSource = System.getProperty(PROP_EGD, "");
            if (egdSource.length() != 0) {
                return egdSource;
            }
            egdSource = Security.getProperty(PROP_RNDSOURCE);
            if (egdSource == null) {
                return "";
            }
            return egdSource;
        }
    });
}
如果来源是

final static String URL_DEV_RANDOM = "file:/dev/random";

使用
NativeSeedGenerator
,在Windows上尝试在Linux上使用本机
CryptoAPI
,该类仅扩展
SeedGenerator.URLSeedGenerator

package sun.security.provider;

import java.io.IOException;

/**
 * Native seed generator for Unix systems. Inherit everything from
 * URLSeedGenerator.
 *
 */
class NativeSeedGenerator extends SeedGenerator.URLSeedGenerator {

    NativeSeedGenerator() throws IOException {
        super();
    }

}
并调用默认情况下加载
/dev/random
的超类构造函数

URLSeedGenerator() throws IOException {
    this(SeedGenerator.URL_DEV_RANDOM);
}
因此,OpenJDK默认使用
/dev/random
,直到您没有在系统属性
java.security.egd
或安全属性文件的属性
securerandom.source
中设置另一个值为止

如果要使用
strace
查看读取结果,可以更改命令行并添加
trace=open,read
表达式

sudo strace -o a.strace -f -e trace=open,read java class
您可以看到类似的内容(我使用OracleJDK6进行了测试)

更快启动的Tomcat Wiki部分建议,如果您在启动过程中遇到延迟,请使用非阻塞熵源,如/dev/uradom

更多信息:


希望这有帮助。

问题不在于SecureRandom本身,而在于/dev/random如果没有足够的数据就会阻塞。您可以使用Uradom,但如果您需要加密的强随机种子,这可能不是一个好主意。 在无头Linux系统上,您可以安装haveged守护进程。这将为/dev/random添加足够的数据,以便调用不必等待生成所需的熵。
我在Debian Aws实例上做了这项工作,看到SecureRandom generateBytes调用从25秒下降到亚毫秒(Openjdk 1.7之类的,不记得具体是哪个版本)

您可以尝试一个小应用程序,创建一个新的随机生成器(使用
newsecurerandom
),然后从中读取一些字节,看看是否从
urandom
读取。但是,请确保您的目标是相同的Java运行时,并检查是否未使用Tomcat的
Java-D
设置
Java.security.egd
属性。我确实运行了一个示例程序(代码取自链接上的问题)。它既不是从/dev/random读取的,也不是从/dev/random读取的,如问题所附的strace日志所示。您还可以检查
jre/lib/security/java.security
并检查
securerandom.source
是如何定义的吗?谢谢@owlstead。它是/dev/uradom。你能试试那里的
/dev//uradom
看看会发生什么吗?感谢
读取的
跟踪,我确认
\dev\uradom
正在这个JVM中使用。没有egd覆盖和securerandom.source也是
\dev\uradom
。所以,这排除了SecureRandom作为原因的可能性,我将不得不研究其他可能的原因。
final static String URL_DEV_URANDOM = "file:/dev/urandom"
package sun.security.provider;

import java.io.IOException;

/**
 * Native seed generator for Unix systems. Inherit everything from
 * URLSeedGenerator.
 *
 */
class NativeSeedGenerator extends SeedGenerator.URLSeedGenerator {

    NativeSeedGenerator() throws IOException {
        super();
    }

}
URLSeedGenerator() throws IOException {
    this(SeedGenerator.URL_DEV_RANDOM);
}
sudo strace -o a.strace -f -e trace=open,read java class
13225 open("/dev/random", O_RDONLY)     = 8
13225 read(8, "@", 1)                   = 1
13225 read(3, "PK\3\4\n\0\0\0\0\0RyzB\36\320\267\325u\4\0\0u\4\0\0 \0\0\0", 30) = 30
....
....