一段孤独的代码 一段孤独的代码

A Lonely Code

目录
记一次想也没想到的java使用apache-sshd连接ssh时间超长
/        

记一次想也没想到的java使用apache-sshd连接ssh时间超长

原始情况

第三方通过连接服务进行对设备的访问,连接服务对设备连接并登录设备,第三方表示连接设备登录时间过长。

调查

通过 Arthas 对服务进行检查,发现在四个小时的时间中,总共一千多次请求中有 40 次请求时间超过了 10 秒。

蛤...我想不通他们说时间过长是为啥,一千次中 40 次平均到他们头上也没几次吧

除非这四十次都是他们的请求。调查下吧 🤦‍

结果...还真是,四十次全是他们的请求。❓,大哥你啥时候买彩票,我和你买一样的号。

玩笑到此,四十次全是他们的请求,这绝不是巧合。

利用 Arthas 追踪代码运行时间,发现 org.apache.sshd.SshClient 类的 setUpDefaultClient 方法执行时间占比过长,但不是全都长时间,一百次中有一次 ❓这是为啥。

再往下追踪,还挺麻烦的,得好一会才能找到一个异常的

好吧,追到这里已经明确知道问题出在哪里了,但是为什么出现问题还要找一找,面向百度编程,让我们百度一下找找。

https://blog.csdn.net/weixin_34375054/article/details/94714354

https://blog.csdn.net/chenxiusheng/article/details/105231357?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-3

java.security.SecureRandom类的注释上写着

什么意思呢,就是说由于不同平台系统的实现方法,可能会造成 generateSeednextBytes出现阻塞情况。比如在类 Unix 系统中通过读取 /dev/random实现。

/dev/random

这是个啥玩意,类 Unix 系统中这是一个特殊的设备文件,通过收集设备的噪音实现了高随机的随机数,但是这样有个问题存在,如果噪音不够会怎么样?

如果噪音不够,读取操作将会阻塞,直到设备产生了足够的噪音能够生成随机数。

解决方法

问题找到了,解决方法也找到了,通过添加 Java 运行参数 -Djava.security.egd=file:/dev/./urandom

这个参数是什么意思呢?

参数表示,要求 JavaSecurity 通过读取 /dev/./urandom生成随机数。

注:OracleJDK 是通过 /dev/random生成随机数的,OpenJDK 是通过 /dev/urandom生成的,也就是说这个问题只发生在类 Unix 的 OracleJDK 中。

结束

问题发生时,我想了很多种可能的原因,数据库原因,代码中存在的锁,第三方包的问题,网络波动问题,设备侧慢的情况等等,但是就没想到是因为 JDK 的原因。

为什么同样的设备一直慢,对此估计上是他们设备 SSH 算法设置问题造成随机密钥生成时消耗较大,再加上设备噪音偏低,

启发

别相信任何代码不会出问题,哪怕 JDK 的也有坑等着你。


标题:记一次想也没想到的java使用apache-sshd连接ssh时间超长
作者:GunVeda
地址:http://gunveda.top/articles/2020/06/18/1592491280170.html