代码之家  ›  专栏  ›  技术社区  ›  Stephan

如何保护应用程序免受虚拟机时间跟踪丢失问题的影响?

  •  1
  • Stephan  · 技术社区  · 10 年前

    脚本

    我们有一个用Java编写的应用程序。它曾经在物理机器上平稳运行。 已决定移动到虚拟机。现在,该应用程序在日志的时间戳中定期显示错误。

    插图

    虚拟化之前

    Timestamp    | Caller | Message
    00:00:01.735 |  foo   | Downloading something
    00:00:05.123 |  foo   | Downloaded something
    00:00:05.123 |  bar   | Analyzing something
    ...
    00:00:08.990 |  foo   | END
    

    如您所见,时间戳值在物理机器上持续增长。

    虚拟化之后

    Timestamp    | Caller | Message
    00:00:01.735 |  foo   | Downloading something
    00:00:05.123 |  bar   | Downloaded something
    00:00:05.123 |  baz   | Analyzing something
    ...
    00:00:04.485 |  foo   | END
    

    现在,日志表明下载过程结束。

    采取的解决方案

    我们已将VM与NTP服务器同步。这个问题消失了好几天。现在又回来了。

    问题

    • 我们应该更频繁地同步吗?
    • 我们能想象以某种方式覆盖吗 System.currentTimeMillis() ?
    • 我们是否应该根据检测到的时间漂移来更改日志中的时间戳值?
    • 如何解决虚拟机时间跟踪丢失问题?

    主机操作系统: 第6.5节
    来宾操作系统: 第5.4节
    虚拟化平台: 第3.4节

    3 回复  |  直到 6 年前
        1
  •  1
  •   Toilal    10 年前

    你必须在不同的选项之间做出选择

    • 有一个精确的时间,更频繁的时间同步,但时间戳排序更不一致。。。
    • 通过减少时间同步的频率,或者甚至完全禁用时间同步,可以获得更精确的时间,但时间戳排序更一致。。。

    据我所知,在硬件计算机中不可能有同样的精度。

        2
  •  1
  •   Stephan    10 年前

    最后,这是RHEL 5.4中的一个错误。将来宾操作系统升级到RHEL 5.11解决了这个问题。

        3
  •  1
  •   CosmicGiant    10 年前

    currentTimeMillis() 是线程安全的开箱即用,但由于它基于操作系统的时钟时间,如果系统的时钟发生变化,它可能会出现不准确的情况 时间漂移 (误差累积增加)。

    nanoTime() 线程安全,但使用系统的“原子钟”( 如果可能的话* ),正在 有免疫力 对系统时钟的更改 适当的 如果你的目标只是在独立于它的事件上打印时间戳 不易受影响 在用于以下操作的循环中使用时的时间漂移 取决于* 从中,尽管在很长的时间内,时间漂移会变得明显。

    • * -某些特定操作系统根本不提供或支持“原子钟”,在这些特定情况下,Java 别无选择 而是使用正常时钟。如果您怀疑您的系统可能是其中之一,请搜索它。
    • * -我的意思是 “从属” 这里的操作是指方法或操作由同一个或不同方法的上一次调用后经过的时间触发,或具有依赖于该时间的值,如 游戏循环 .
      • 发生这种情况是因为时间戳只是一个时间戳,它没有考虑到操作本身执行所需的时间。

    这似乎不是你的情况,但如果你曾经遇到过这样的情况 依靠的 在上一节最后一个注释中解释的时间戳上,您要做的是实现 三角洲时间 ,它使用 纳米时间() 时间戳,以获得测量之间经过时间的准确关系,但这也允许使用增量。

    增量时间是正确的方法 动画 例如