• 0
  • 0
分享

UUID(Universally Unique Identifier,通用唯一标识符)是一种用于标识信息的128位标识符。Java开发人员倾向于使用 java.util.UUID#randomUUID API来生成UUID编号(类似4c88314f-14ca-4652-8567-4471a0ef917c)。

UUID通常用于标识数据记录、会话、文件、对象等,以确保它们在不同上下文中的唯一性。注意,UUID是一种全局唯一性标识符,不保证在不同时间生成的UUID之间是有序的或可比较的,因此不应该依赖于UUID的大小或顺序。

在某些情况下,使用这个API可能对应用程序的可用性产生负面影响。下面,我们将通过一个实际案例来深入讨论这一问题。

randomUUID如何工作

java.util.UUID#randomUUID API在内部使用操作系统中的entropy来生成一个唯一的数字。entropy是什么意思Linux内核使用某些技术,如用户的鼠标移动,硬件风扇噪音的变化,设备驱动程序噪音的变化,来生成随机数。当操作系统中缺乏熵时,随机数生成将减慢。当出现减速时,调用此 java.util.UUID#randomUUID 的应用程序线程将被置于BLOCKED状态,严重时会让程序处于暂停状态。

真实的世界应用程序-java.util.UUID#randomUUID()API中阻塞的50个线程

下面是一个应用程序的实际线程转储报告,该应用程序正遭受此问题的困扰。在线程转储报告中,我们可以注意到总共有102个线程。在这102个线程中,有50个线程由于java.util.UUID#randomUUID API而处于BLOCKED状态。下面是这50个线程之一的堆栈跟踪:

"[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'" waiting for lock java.security.SecureRandom@20a56b2b BLOCKED
 
java.security.SecureRandom.nextBytes(SecureRandom.java:433)
java.util.UUID.randomUUID(UUID.java:159)
com.buggycompany.jtm.bp.<init>(bp.java:185)
com.buggycompany.jtm.a4.f(a4.java:94)
com.buggycompany.agent.trace.RootTracer.topComponentMethodBbuggycompanyin(RootTracer.java:439)
weblogicx.servlet.gzip.filter.GZIPFilter.doFilter(GZIPFilter.java)
weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3730)
weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

由于缺少 entropy,线程在调用 java.util.UUID#randomUUID 时进入了BLOCKED状态,无法继续执行代码。这50个线程被卡住了。

解决方案

JDK升级

这个问题是由Java中的一个已知bug引起的。但是,自JDK 8 u112或JDK 9 b105以来,它已被修复。所以最优先的解决方案就是升级你的JDK版本。

Linux安装Haveged

如果你的Java程序运行在Linux中,那么可以考虑安装haveged库。haveged项目旨在提供一个易于使用的,不可预测的随机数生成器,基于HAVEGE算法的适应。这里是Haveged项目GIT仓库页面。以下是如何安装它:

在基于Debian的平台(Debian,Ubuntu)上:

sudo apt-get install rng-tools
sudo update-rc.d haveged defaults

在Redhat平台(RHEL、Fedora、CentOS)上:

sudo yum install rng-tools
sudo chkconfig haveged on

用/dev/urandom代替/dev/random

类Unix操作系统提供了特殊的文件/dev/random,用作伪随机数生成器。Java使用这个文件来生成随机数。可以将其配置为使用/dev/urandom而不是/dev/random。

/dev/urandom是另一个能够生成随机数的特殊文件。然而,由于随机性较小,它具有降低安全性的缺点。如果需要的话,可以通过在启动过程中将下面的JVM参数传递给你的Java程序来实现它:

-Djava.security.egd=file:/dev/./urandom
FunTester原创专题推荐~

  • 900原创合集
  • 2021年原创合集
  • 2022年原创合集
  • 接口功能测试专题
  • 性能测试专题
  • Groovy专题
  • Java、Groovy、Go、Python
  • 单测&白盒
  • FunTester社群风采
  • 测试理论鸡汤
  • FunTester视频专题
  • 案例分享:方案、BUG、爬虫
  • UI自动化专题
  • 测试工具专题


  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • JMeter原生支持多种不同的取样器(HTTP、TCP、JDBC、JMS等),每一种不同类型的取样器可以向服务器发送不同协议类型的请求。除了开箱即用的协议支持以外,JMeter还支持用户自己开发新协议的测试插件来进行扩展。用户开发定制化的取样器插件,首先需要开发取样器的图形界面,扩展实现JMeter的AbstractSamplerGui类;然后开发取样器的处理逻辑类,扩展实现JMeter的AbstractSampler类,实现协议交互,发送请求报文并处理返回的响应结果;最后将开发调试好的代码编译,与描述了依赖关系的pom.xml一起打成JAR包,拷贝到JMeter的lib\ext目录下,其它相...
            1 1 2668
            分享
          •   10 月 8 日,杭州亚运会正式落下大幕,在这场大会期间,中国体育代表团获得的金牌总数达到 201 枚。  而就在刚刚,联想也公布了另一组“夺冠”数据 —— 亚运会期间,联想近万台昭阳笔记本和 ThinkCentre M 大师台式机连续 30 天不关机高能稳定运行。  据介绍 ,此次亚运会期间,联想提供了近万台昭阳笔记本和 ThinkCentre M 大师系列台式机,为亚运赛事提供服务和支持。也是这些产品,创造了 30 天长时间持续工作不关机、0 故障的记录。  据了解,9 月 18 日,杭州亚运会主媒体中心进入正式运行阶段,在这里的公共办公区,部署了联想 ThinkCentre M 大师...
            0 0 916
            分享
          • 不论你是什么时候开始接触测试这个行业的,你首先听说的应该是功能测试。通过一些测试手段来验证开发做出的代码是否符合产品的需求?当然你也有自己对功能测试的理解,但是最近两年感觉功能测试好像不太受欢迎,同时不少同学真的是功能测试都没有做好,就去尝试自动化测试,测试开发什么的,结果是越学越迷茫,这是为什么呢?究其原因是,你功能测试还没有学好呢!我们通常认为的功能测试是根据需求,采取如下测试流程:需求分析,用例编写,用例评审,提测验证,Bug回归验证,上线与线上回归等来进行测试。如此日复一日,年复一年,响应了很多需求,可是想换工作的时候却得不到认可,大家想想是不是这种情况?下面我就以一个功能测试人员如何...
            1 0 1119
            分享
          •   产品功能测试与系统测试有什么区别呢?这常常是让测试人员非常迷惑的地方,有的小伙伴认为系统测试应该包含功能测试在内,有的小伙伴则认为这是两个独立的测试类别。而从很多方面来说,产品功能测试与系统测试还是有很大区别的,小编就简单分析一下,两者的相似与不同之处,以及如何做好功能测试?  一、产品功能测试与系统测试分别是什么意思?  产品功能测试是指对软件产品或者程序各项功能进行验证,根据功能测试用例进行逐项检查,看各项功能是否能正常使用,并在此过程中发现软件存在的潜在问题。通常功能测试不考虑系统内部的结构及代码情况,所以也称为黑盒测试。  系统测试是指对产品的硬件软件以及应用场景进行系统的测试,模...
            0 0 1240
            分享
          • 1、场景在做性能测试时,单台机器进行压测可能达不到预期结果。主要原因是单台机器压到一定程度会出现瓶颈。也有可能单机网卡跟不上造成结果偏差较大。例如4C8G的window server机器,使用UI方式,最高压测在1800并发(RT 20ms以内)左右。如果对于XML文件进行解析,更容易吃CPU,并发数会更低。当单台机器不能支持更大的并发时需要考虑分布式压力测试。 2、原理原理图如下:Jmeter分布式测试时,选择其中一台作为调度机(master),其它机器做为执行机(slave)master通过GUI界面启动slave机器,将jmeter压测发送给每台启动的slaveslave启动j...
            6 8 3511
            分享
      • 51testing软件测试圈微信