• 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自动化专题
  • 测试工具专题


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

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   一、自我介绍  这里就不过多阐述了,相信很多小伙伴都有。  二、灵活问题  1、大概说说之前公司的测试流程。  2、测试报告有哪些内容?  3、如何保证用例的覆盖度?  4、什么是测试用例,什么是测试脚本?两者的关系?  5、Bug的级别,按照什么划分。  6、你认为是bug,开发认为不是bug,如何解决?  7、给你-一个网站,你如何测试?  8、你印象中最深刻的bug?  9、如果没有需求文档怎么办?  10、Andriod兼容性测试选取手机的准则?  三、功能方面  1、说一下测试用例的设计方法?2、说说web和app测试的区别?  2、小程序和app测试有什么区别?  3、Andr...
            0 0 834
            分享
          •        测试过程在瀑布式开发中作为开发流程中的一个环节,只能在实现软件基础后开始运行,这种模式很大程度上导致了人力资源的浪费。而在敏捷开发模式中,为了解决人力资源浪费的问题,团队的开发过程需要践行敏捷,同样,测试阶段也要践行敏捷。       测试过程有没有必要性?       测试人员如同食品生产的质检员,能够依据交付成果检验产品的完成标准,并对产品判定“合格”与否。也就是说,测试人员需要测试产品的各功能点,对出现BUG的部分进行汇总分析,最终提交到开发人员手上。&n...
            0 0 1985
            分享
          •   一般做银行测试,会给到测试人员需求说明书,用需求说明书怎么编写测试用例呢?我这次带大家一步一步的编写测试用例。  需求描述:  业务规则:1.大额存单兑取类型分为发售期内兑付、提前部分支取(利随本清支取部分靠档计息,定期付息支取部分活期计息并进行倒扣处理)、提前全部支取(利随本清支取部分靠档计息,定期付息支取部分活期计息并进行倒扣处理)、到期兑付和逾期兑付(只允许全部兑付)。系统自动根据兑取交易日期及兑取金额默认兑取类型。大额存单兑付后将本息资金划转到投资人认购本期大额存单的活期存款账户内,但因办理存款证明、质押、冻结等业务导致状态异常的大额存单不可兑付。  通过这个需求,可以分析出以下的...
            0 1 726
            分享
          • 常用的Android自动化测试框架包括UIAutomator、Appium以及Monkeyrunner等;其中,UIAutomator是谷歌在发布Android4.1版本时推出的一款基于Java语言的UI测试框架,由此,UIAutomator只能运行在4.1及其以上版本中。本篇文章将为大家介绍如何搭建基于Java+UIAutomator的测试环境。一、UIAutomator简介首先,作为Google自家推出的一款开源的UI自动化测试框架,其稳定性和可靠性可以得到极大的保障,运行时也有更多的权限。其次,UIAutomator可以跨进程操作,运行速度较快;但是UIAutomator不支持Andro...
            0 3 2883
            分享
          • SoapUI Windows 版本下载今天带大家过一遍 SoapUI 在 Windows 系统下的安装教程吧!各位 开发小伙伴 们可以跟着我一起来~下载安装包下载链接:https://www.soapui.org/downloads/soapui/安装安装非常简单,只需双击它即可启动,安装程序将立即启动就可以看到开始安装的界面了一直点击 下一步,并设置安装的路径,默认是:C:\Program Files\SmartBear\SoapUI-5.5.0勾选你所需要的安装组件最后会有一个进度条,我们只需要等待进度条到 100%最后安装成功体验 SoapUI接下来带大家简单体验一下:使用 SoapUI...
            0 0 1043
            分享
      • 51testing软件测试圈微信