Java 随机生成的UUID具有重复项

Java 随机生成的UUID具有重复项,java,random,jvm,uuid,production,Java,Random,Jvm,Uuid,Production,我正在使用下面的函数生成UUID UUID.randomUUID().toString() 在生产环境中,我们有50多台服务器(应用程序服务器-每台服务器本身都是一个JVM),对于这些服务器中的请求,我们首先生成一个UUID,它本质上唯一地标识一个事务 我们观察到,在服务器6和服务器11中,生成的UUID每天至少匹配10到15条消息,这很奇怪,因为考虑到负载(即每天大约100万个事务),这些UUID在同一天内重复是非常奇怪的 这就是我们迄今为止所做的 验证了应用程序日志-我们没有发现任何可疑之

我正在使用下面的函数生成UUID

UUID.randomUUID().toString()
在生产环境中,我们有50多台服务器(应用程序服务器-每台服务器本身都是一个JVM),对于这些服务器中的请求,我们首先生成一个UUID,它本质上唯一地标识一个事务

我们观察到,在服务器6和服务器11中,生成的UUID每天至少匹配10到15条消息,这很奇怪,因为考虑到负载(即每天大约100万个事务),这些UUID在同一天内重复是非常奇怪的

这就是我们迄今为止所做的

  • 验证了应用程序日志-我们没有发现任何可疑之处,所有日志都正常
  • 尝试在测试环境中以类似的生产负载和50多台服务器复制此问题,但在测试环境中没有发生
  • 检查了应用程序逻辑-这似乎不是问题,因为除6和11之外的所有其他48台服务器(它们具有相同代码库的副本)都工作正常,并且它们正在为每个事务生成唯一的UUID

  • 到目前为止,我们还无法跟踪问题,我的问题基本上是,我们是否缺少JVM级别的某些东西,或者我们需要为这类问题设置UUID参数?

    给定时间,我相信您会找到罪魁祸首。与此同时,我认为有一条评论值得推广以回答:


    您正在多个位置生成伪随机UUID。如果找不到其他bug,可以考虑在一个位置生成所有伪随机UUIDs,或者生成真正的随机UUIDs < /P> 因此,创建一个UUID服务器。这只是一个产生UUID块的过程。每个块可能包含10000个(或任何合适的)UUID。在进程验证块不包含重复项后,进程将每个块写入磁盘


    创建另一个进程来分发UUID块。可能它只是一个web服务,在收到请求时返回一个未使用的块。事务服务器请求一个块,然后在创建事务时使用这些UUID。当服务器使用了大部分分配的UUID时,它会请求另一个块。

    我不会浪费时间去想
    UUID.randomUUID()
    是如何每天生成几个重复的UUID的。这种偶然发生的可能性微乎其微。(如果基础RNG状态是重复的,则可以生成整个系列的重复项,但情况似乎并非如此。)


    相反,要寻找一台服务器存储的UUID可能与另一台服务器存储的UUID发生冲突的地方。为什么这只发生在50台服务器中的2台服务器之间?这与您尚未共享的环境和系统的细节有关。

    如上所述,合法冲突的可能性非常小。更可能的情况是,值在对象之间以不正确的方式传输

    对于像java那样通过引用传递的语言,请考虑下面的脚本

    saveObject1.setUUID(initObj.getUUID())
    initObj.setUUID(UUID.randomUUID());
    saveObject2.setUUID(initObj.getUUID()) 
    
    在本例中,saveObject1和saveObject2将具有相同的值,因为它们都指向相同的对象引用(initObj的UUID引用)


    像这样的问题似乎比实际的UUID更可能是冲突,特别是如果您能够重现它的话。当然,如果它不是一直发生,可能是更复杂的情况,比如一个罕见的竞争条件,initObj没有及时重新初始化,导致saveObject1和2共享同一个对象引用

    这可能是无用的建议,但如果您找到了一种生成V1(基于MAC+时间戳)而不是V4的方法,它可能会减少冲突,因为它们必须在同一时间、同一台机器上发生,而且非常不幸。作为第一步,我将记录从
    UUID.randomUUID()生成的每个UUID
    在每台机器上输入本地文本文件。然后,我将在这些日志上重新运行重复搜索。这可能是因为在您的实际代码中,UUID在稍后阶段会混淆,例如,由于更高级别层中的某个竞争条件。我还将在您的整个代码库中搜索您可能正在播种任何随机数生成器的任何位置。;-)您正在多个位置生成伪随机UUID。如果找不到其他bug,可以考虑在一个位置生成所有伪随机UUIDs,或者生成真正的随机UUID。在正常操作下,由虚拟机生成的随机数不应该显示这种冲突。但是,假设您使用虚拟机a生成了一组随机数。然后拍摄了a的快照。然后,某个时候,停止了a,从快照恢复,并恢复生成随机数-由于内部状态值的恢复,您可能会有一些重复。我怀疑,如果您快照了A,然后从快照中启动了A和B,您可能会遇到相同的问题。