Random的子类 SecureRandom 在k8s系统下的pod生成随机数特别慢问题

问题描述:我们使用一个SecureRandom.getInstanceStrong() 获取random对象,来生成16位的随机数,然而在生成过程中每次生成pod里面日志看需要将近两分钟生成一个数,这个问题在我本地、预生产、线上都没有问题,只有测试有这个问题。一些是在关键位置打印日志发现的问题

针对整个问题,我们只需要一个唯一标识的字符串,我使用雪花算法代替--临时解决

----------------------------------------------------------------------------------------------------------------------

问题还是要分析具体原因,具体如下:

SecureRandom.getInstanceStrong() 在linux环境下适用/dev/random生成种子,但是它下面的random是一个阻塞数字生成器,如果没有足够的随机数据提供就是一直等待,这就导致了线程的等待。这个随机数据来来自键盘、鼠标、以及磁盘活动产生的随机性生成的数据,如果这个服务缺乏磁盘的活动(linux系统下只有这个,很少会有键盘和鼠标活动)就会导致线程阻塞。

那么 Linux 中随机数是如何产生的呢 PRNG(Pseudo-Random Number Generator)

Linux 内核采用熵来描述数据的随机性,熵(entropy)是描述系统混乱无序程度的物理量,一个系统的熵越大则说明该系统的有序性越差,即不确定性越大。内核维护了一个熵池用来收集来自设备驱动程序和其它来源的环境噪音。理论上,熵池中的数据是完全随机的,可以实现产生真随机数序列。为跟踪熵池中数据的随机性,内核在将数据加入池的时候将估算数据的随机性,这个过程称作熵估算。熵估算值描述池中包含的随机数位数,其值越大表示池中数据的随机性越好。内核中随机数发生器 PRNG 为一个字符设备 random,代码实现在 drivers/char/random.c,该设备实现了一系列接口函数用于获取系统环境的噪声数据,并加入熵池。系统环境的噪声数据包括设备两次中断间的间隔,输入设备的操作时间间隔,连续磁盘操作的时间间隔等。对应的接口包括

void add_device_randomness(const void *buf, unsigned int size);
void add_input_randomness(unsigned int type, unsigned int code,
				unsigned int value);
void add_interrupt_randomness(int irq, int irq_flags);
void add_disk_randomness(struct gendisk *disk);

内核提供了 1 个的接口来供其他内核模块使用。

该接口会返回指定字节数的随机数。random 设备了提供了 2 个字符设备供用户态进程使用——/dev/random 和/dev/urandom:

  • /dev/random 适用于对随机数质量要求比较高的请求,在熵池中数据不足时, 读取 dev/random 设备时会返回小于熵池噪声总数的随机字节。/dev/random 可生成高随机性的公钥或一次性密码本。若熵池空了,对/dev/random 的读操作将会被阻塞,直到收集到了足够的环境噪声为止。这样的设计使得/dev/random 是真正的随机数发生器,提供了最大可能的随机数据熵。
  • /dev/urandom,非阻塞的随机数发生器,它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom 的读取操作不会产生阻塞,但其输出的熵可能小于/dev/random 的。它可以作为生成较低强度密码的伪随机数生成器,对大多数应用来说,随机性是可以接受的。

解决方案

有了以上的的解释,我们就知道解决方案了,使用 /dev/urandom 这种非阻塞的方式来产生随机数即可解决问题,在 Java 中我们改成如下写法即可解决问题

SecureRandom random = new SecureRandom();

new SecureRandom() 使用 /dev/urandom 生成种子,不会产生阻塞。

参考文章:

1. SecureRandom.getInstanceStrong()引发的线程阻塞问题分析_磨唧的博客-CSDN博客

2.  使用 SecureRandom 产生随机数采坑记录 - 云+社区 - 腾讯云

3. SecurityRandom的getInstanceStrong() 阻塞问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值