区块链技术博客
www.b2bchain.cn

服务响应时间慢:Java SecureRandom和/ dev / random – java程序员分享

本文介绍了服务响应时间慢:Java SecureRandom和/ dev / random – java程序员分享,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

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

  • 第一个调用恰好在Tomcat重新启动后(即使请求在启动后4分钟到达)也仅需 30.0 xy秒
  • 稍后,某些调用恰好需要 15.0 pq秒(没有可以建立的特定模式,pq是TP99中花费的时间)。
  • 服务调用涉及加密和解密(AES / ECB / PKCS5Padding)。

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

    (尽管在catalina.log中写了一个日志,上面写着"Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [28,760] milliseconds.")

    另外,为了检查是否正在使用/dev/random/dev/urandom,我使用了this question的测试。令我惊讶的是,与链接问题中发生的情况不同,我没有看到它们中的任何一个。
    这些是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 

    那么,什么用于播种SecureRandom?

    fyi,java -version

    java version "1.6.0_32" OpenJDK Runtime Environment (IcedTea6 1.13.4) (rhel-7.1.13.4.el6_5-x86_64) OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode) 

    参考方案

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

    SecureRandom使用SeedGenerator获取种子字节

    public byte[] engineGenerateSeed(int numBytes) {     byte[] b = new byte[numBytes];     SeedGenerator.generateSeed(b);     return b; } 

    SeedGenerator从SunEntries获取seedSource(字符串)

    String egdSource = SunEntries.getSeedSource(); 

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

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

    SeedGenerator检查此值以初始化实例

    // Static instance is created at link time private static SeedGenerator instance;  private static final Debug debug = Debug.getInstance("provider");  final static String URL_DEV_RANDOM = SunEntries.URL_DEV_RANDOM; final static String URL_DEV_URANDOM = SunEntries.URL_DEV_URANDOM;  // Static initializer to hook in selected or best performing generator static {     String egdSource = SunEntries.getSeedSource();      // Try the URL specifying the source     // e.g. file:/dev/random     //     // The URL file:/dev/random or file:/dev/urandom is used to indicate     // the SeedGenerator using OS support, if available.     // On Windows, the causes MS CryptoAPI to be used.     // On Solaris and Linux, this is the identical to using     // URLSeedGenerator to read from /dev/random      if (egdSource.equals(URL_DEV_RANDOM) || egdSource.equals(URL_DEV_URANDOM)) {         try {             instance = new NativeSeedGenerator();             if (debug != null) {                 debug.println("Using operating system seed generator");             }         } catch (IOException e) {             if (debug != null) {                 debug.println("Failed to use operating system seed "                               + "generator: " + e.toString());             }         }     } else if (egdSource.length() != 0) {         try {             instance = new URLSeedGenerator(egdSource);             if (debug != null) {                 debug.println("Using URL seed generator reading from "                               + egdSource);             }         } catch (IOException e) {             if (debug != null)                 debug.println("Failed to create seed generator with "                               + egdSource + ": " + e.toString());         }     }      // Fall back to ThreadedSeedGenerator     if (instance == null) {         if (debug != null) {             debug.println("Using default threaded seed generator");         }         instance = new ThreadedSeedGenerator();     } } 

    如果来源是

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

    要么

    final static String URL_DEV_URANDOM = "file:/dev/urandom" 

    在Windows上使用NativeSeedGenerator尝试在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); } 

    因此,在没有在系统属性/dev/random或安全属性文件的java.security.egd属性中未设置其他值之前,OpenJDK默认使用securerandom.source

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

    sudo strace -o a.strace -f -e trace=open,read java class 

    您会看到类似的内容(我使用Oracle JDK 6进行了测试)

    13225 open("/dev/random", O_RDONLY)     = 8 13225 read(8, "@", 1)                   = 1 13225 read(3, "PK34nRyzB36320267325u4u4 ", 30) = 30 .... .... 

    如果您在启动过程中遇到延迟,请参阅“Tomcat Wiki”部分中有关加快启动速度的建议,使用/ dev / urandom之类的非阻塞熵源

    更多信息:https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source

    希望这可以帮助。

    Java-搜索字符串数组中的字符串 – java

    在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…

    产生6位数的随机数 – java

    我只想生成6位数的随机数,范围应从000000到999999。new Random().nextInt(999999)返回我的电话号码,但不是6位数字。 参考方案 就这么简单,您可以使用您的代码,并在此处做一件事String.format("%06d", number); 这将以字符串格式返回您的数字,因此“0”将为“000000”。这是…

    Java Scanner读取文件的奇怪行为 – java

    因此,在使用Scanner类从文件读取内容时,我遇到了一个有趣的问题。基本上,我试图从目录中读取解析应用程序生成的多个输出文件,以计算一些准确性指标。基本上,我的代码只是遍历目录中的每个文件,并使用扫描仪将其打开以处理内容。无论出于何种原因,扫描程序都不会读取其中的一些文件(所有UTF-8编码)。即使文件不是空的,scanner.hasNextLine()在…

    Java Globbing模式以匹配目录和文件 – java

    我正在使用递归函数遍历根目录下的文件。我只想提取*.txt文件,但不想排除目录。现在,我的代码如下所示:val stream = Files.newDirectoryStream(head, "*.txt") 但是这样做将不会匹配任何目录,并且返回的iterator()是False。我使用的是Mac,所以我不想包含的噪音文件是.DS_ST…

    直接读取Zip文件中的文件-Java – java

    我的情况是我有一个包含一些文件(txt,png,…)的zip文件,我想直接按它们的名称读取它,我已经测试了以下代码,但没有结果(NullPointerExcepion):InputStream in = Main.class.getResourceAsStream("/resouces/zipfile/test.txt"); Buff…

    赞(0) 打赏
    部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 服务响应时间慢:Java SecureRandom和/ dev / random – java程序员分享
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址

    b2b链

    联系我们联系我们