问题描述
使用Ruoyi-cloud 二开,将服务部署到虚拟机上后,准备登录,发现验证码一致加载不出来,接口请求超时!
解决步骤
- telnet 虚拟机ip+port 发现可以通.
- curl 接口,发现一致不返回,超时了.
- /code 接口超时,一步一步log,测试后发现在迭代验证码时超时,询问ai.
结论
SecureRandom.getInstancestrong()方法会返回一个"强"随机数生成器,它需要收集足够的系统熵(随机性)才能生成随机数。在某些系统环境下,特别是虚拟机或源不足的服务器上,这个过程可能会阻塞很长时间,等待系统收集足够的随机熵。
学习到的知识
什么是系统熵?
熵源包括:
- 键盘敲击的时间间隔
- 鼠标移动的轨迹和时间
- 硬盘读写的时间差
- 网络数据包到达的时间
- 中断发生的时间
- CPU温度变化
- 内存访问模式
- 系统调用的时间差
Linux系统中的熵:
存储在 /dev/random 和 /dev/urandom 中内核维护一个熵池,收集各种不可预测的事件可以通过 cat /proc/sys/kernel/random/entropy_avail 查看当前可用熵
为什么会阻塞?
熵不足的情况:
- 虚拟机环境:缺少真实硬件的随机性
- 服务器环境:无键盘鼠标交互,硬件活动单一
- 嵌入式设备:硬件资源有限
- 刚启动的系统:还没收集足够的随机事件
SecureRandom.getInstanceStrong()
→ 要求高质量熵
→ 熵池不足时等待
→ 系统收集更多随机事件
→ 阻塞直到熵足够
不同随机数生成器的区别
-
new Random()
伪随机数生成器
基于算法,可预测
性能最好,但不安全 -
new SecureRandom()
使用系统熵,但有后备算法
熵不足时使用算法扩展
平衡了安全性和性能 -
SecureRandom.getInstanceStrong()
要求最高质量的熵
熵不足时会阻塞等待
最安全但可能性能很差