在Java中生成唯一ID,以标记日志中的相关条目组

在Java中生成唯一ID,以标记日志中的相关条目组,java,datetime,logging,uuid,Java,Datetime,Logging,Uuid,关于这个话题,有好几篇文章。每个人都在谈论一种特定的方法,所以他们只想在一个问题上进行比较 我正在尝试实现一个功能,在这个功能中,我们能够识别日志文件中的某些事件。这些事件需要与唯一的id关联。 我正试图为这一独特的身份生成提出一个策略。 ID必须包含两个部分: 一些静态信息+一些动态信息 当需要调试事件时,可以在日志中搜索模式。 我有三种方法: 静态信息+Joda日期时间(“abc”+2014-01-30T12:36:12.703) 静态信息+原子整数 静态信息+UUID 对于这个问题

关于这个话题,有好几篇文章。每个人都在谈论一种特定的方法,所以他们只想在一个问题上进行比较

我正在尝试实现一个功能,在这个功能中,我们能够识别日志文件中的某些事件。这些事件需要与唯一的id关联。 我正试图为这一独特的身份生成提出一个策略。 ID必须包含两个部分: 一些静态信息+一些动态信息 当需要调试事件时,可以在日志中搜索模式。 我有三种方法:

  • 静态信息+Joda日期时间(“abc”+2014-01-30T12:36:12.703)
  • 静态信息+原子整数
  • 静态信息+UUID
对于这个问题的范围,不考虑多个JVM。 我需要在一个JVM上高效地生成唯一ID。此外,我将无法使用依赖于数据库的解决方案

上述3种策略中哪一种效果最好

  • 如果不是上面提到的,还有其他策略吗
  • Joda基于时间的战略是否稳健?JVM是单一的,但会有并发用户,因此会有并发事件
  • 结合上述/其他策略之一,我是否需要使我的方法线程安全/同步

计算机速度很快,利用时间来尝试创建唯一的价值将失败

而是使用UUID。 从 “[UUID]是表示不可变通用唯一标识符(UUID)的类。”

下面是一些代码:

import java.util.UUID;

private String id;

id = UUID.randomUUID().toString();

我和你有同样的需要,区分日志中相关条目与其他无关条目交错的线程。我已经尝试了你建议的三种方法。我的经历不是Java,而是类似的

日期时间 在我的例子中,我使用的是解析为整秒的日期时间值。这就是粒度太大了。我很容易在同一秒内发生多个事件的碰撞。该死的那些速度快的电脑

对于捆绑的java.util.Date或(强烈建议用于其他目的),两者都解析为毫秒。在现代计算机中,毫秒是很长的时间,所以我不建议这样做

在Java8中,新的(受Joda Time的启发,由定义)解析为纳秒。这似乎是一个更好的标识符,但不是。首先,您的计算机的物理计时时钟可能不支持如此精细的分辨率。另一个原因是计算机的速度越来越快。最后,计算机的时钟可以重置,事实上,当计算机时钟漂移较大时,它经常被重置。现代操作系统通过频繁地在本地或通过互联网检查时钟来重置时钟

而且,日志已经有了时间戳,所以我们使用日期时间作为标识符不会得到任何额外的好处。事实上,在日志条目中有第二个日期时间实际上可能会导致混淆

序列号 所谓“原子整数”,我假设你指的是一个序列号,它是递增的

这对你来说似乎太过分了

  • 您不关心序列,它对于分组日志条目没有任何意义。你根本不在乎一组人是在另一组人之前还是之后排在第n位
  • 维持一个序列是一件痛苦的事,一个潜在的失败点。我总是在维护序列时遇到管理问题
因此,这种方法增加了风险,但没有增加任何特殊好处

UUID 宾果!正是你需要的

通过使用捆绑的java.util.UUID类生成版本3或4 UUID的功能,或者使用第三方库,或者访问命令行的
uuidgen
工具,可以轻松生成

对于非常大的容量,[Version1]UUID(+日期时间+随机数)将是最好的。对于日志记录,UUID(完全随机)是绝对可以接受的

发生碰撞不是一个现实问题。特别是对于为日志生成的有限数量的值。我对那些不理解数字的人感到惊讶,他们说他们永远不会用UUID替换序列。然而,当按下按钮时,我知道的每一个程序员和系统管理员都经历过至少一个序列的失败

不担心线程安全性。不担心争用(请参阅上的测试结果)

UUID的另一个好处是其通常的表示形式,例如:

6536ca53-bcad-4552-977f-16945fee13e2

…很容易辨认。当被识别时,读者立即知道字符串是一个唯一的标识符。因此,它在日志中的存在是自我记录的

我发现UUID是计算的管道胶带。我一直在为它们寻找新的用途

因此,在所讨论的代码开始时,生成一个UUID,然后将其嵌入到每个相关的日志条目中

虽然UUID的十六进制字符串表示法很难读写,但实际上,您只需要扫描开头或结尾的几个数字。或者在我们的现代控制台工具中使用带有搜索和筛选功能的复制粘贴

几个因子
  • UUID在Microsoft世界中被称为
  • UUID不是字符串,而是128位的值。位,只是内存中的位,“开”/“关”值。有些数据库(如)知道如何将UUID作为128位值进行处理和存储。如果我们想向人类展示这些位,我们可以使用一系列128位的“1”和“0”。但人类在读写128位1和0时表现不佳。所以我们使用十六进制表示法。但即使是32个十六进制数字对人类来说也太多了,所以我们将字符串分成组,用连字符分隔,如上图所示,总共36个字符
  • UUID的规范非常明确,十六进制表示应该是小写的。规范说,当从字符串输入创建UUID时,向上