欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Tomcat 生成会话阻塞的思考

最编程 2024-05-05 09:04:09
...

事故现象:

    public void handle(HttpServletRequest request, HttpServletResponse response) {
        //运行到此处的时候会阻塞,然后查看日志就爆出了如下日志  Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [14,387] milliseconds.
        if (request.getSession().getAttribute(WebConstants.SESSION.SESSION_USER_INFO) != null) {
            //...
        }
        //...
    }

原因是  getSession() 时候 需要生成 SessionId,在生成Id的时候需要生成随机数,此时由于采用生成随机数的策略(file:/dev/random)是堵塞的,所以会堵塞很久,解决方案是采用非堵塞(file:/dev/urandom)方式生成随机数。

好了,现在就出现了网上大多数的解决方式,启动参数添加如下参数,具体的原因可参考最下面几个连接

-Djava.security.egd=file:/dev/./urandom

但是,重点来了,如果你的JDK版本是 JDK8,其实启动参数添加以下即可,上下的区别在于多了一个 “./”

-Djava.security.egd=file:/dev/urandom

为何在JDK8 中 不需要添加 “./” ?

请看  SeedGenerator.java 代码,只要你设置了  java.security.egd ,那么就会使用你所指定的生成器,而 JDK7 则不同,请继续往下看

JDK7的代码如下

如果 java.security.egd 参数指定的是 file:/dev/random 或者 file:/dev/urandom,则调用了无参的NativeSeedGenerator构造函数,而无参的构造函数将默认使用 file:/dev/random ,所以在JDK7中如果想要使用 file:/dev/urandom  就必须绕开第一个 if 判断,而使用 file:/dev/./urandom ,这样子才能使用你自定义的生成器

附录:

以下是 getSession()  生成随机数的关键断点处,有兴趣的话,可以动手断点运行一下

参考:

https://blog.****.net/u011687186/article/details/73224733

http://hongjiang.info/jvm-random-and-entropy-source/

http://hongjiang.info/java8-nativeprng-blocking/

https://blog.51cto.com/leo01/1795447

原文地址:https://www.cnblogs.com/fqybzhangji/p/12201885.html

推荐阅读