【问题标题】:How to protect an application against virtual machine time tracking loss issue?如何保护应用程序免受虚拟机时间跟踪丢失问题的影响?
【发布时间】:2015-11-13 20:58:06
【问题描述】:

场景

我们有一个用 Java 编写的应用程序。它曾经在物理机上流畅运行。 已做出迁移到虚拟机的决定。现在,该应用程序在日志的时间戳中经常出现不准确的情况。

插图

虚拟化之前

时间戳 |来电者 |信息 00:00:01.735 |富 |下载东西 00:00:05.123 |富 |下载了一些东西 00:00:05.123 |酒吧 |分析某事 ... 00:00:08.990 |富 |结尾

如您所见,时间戳值在物理机上不断增长。

虚拟化之后

时间戳 |来电者 |信息 00:00:01.735 |富 |下载东西 00:00:05.123 |酒吧 |下载了一些东西 00:00:05.123 |巴兹 |分析某事 ... 00:00:04.485 |富 |结尾

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

采取的解决方案

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

问题

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

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

【问题讨论】:

  • 尚不清楚时间漂移如何直接导致您报告的时间戳不正确。在 VM 上运行 + 时间漂移可能会触发您的应用程序中的问题(可能是竞争条件),这表现为日志问题。

标签: java time virtual-machine virtualization drift


【解决方案1】:

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

  • 具有更频繁的时间同步的精确时间,但时间戳排序更不一致...
  • 通过减少时间同步的频率,甚至完全禁用它来减少精确的时间,但在时间戳排序方面更加一致......

据我所知,不可能达到与硬件计算机相同的精度。

【讨论】:

  • 如何根据检测到的时间漂移​​校正时间戳值?
  • 在某种随机度量上构建计算永远不会带来您可以依赖的东西。有时,VM 时钟会太快,而有时会太慢......如果您真的需要可靠的事件排序,则必须找到时间戳以外的其他内容。
【解决方案2】:

currentTimeMillis() 是开箱即用的线程安全的,但由于它基于操作系统的时钟时间,如果系统的时钟时间发生更改,它可能会出现不准确,并且容易出现时间漂移 em>(不准确度的累积增加)。

nanoTime()不是开箱即用的线程安全,而是使用系统的“原子钟”代替(如果可能* ),对系统时钟的更改免疫,如果您的目标只是打印时间戳或独立于它的事件的时间戳,以及很多 当在循环中用于依赖*的操作时,不太容易发生时间漂移,尽管在很长一段时间内,时间漂移会变得很明显。

  • * - 一些特定的操作系统根本不提供或支持“原子钟”,在这些特定情况下,Java 别无选择但是使用正常时钟。如果您怀疑您的系统可能是其中之一,请用谷歌搜索。
  • * - 我这里所说的 “依赖” 操作是指方法或操作由自上次调用相同或不同的方法,例如在游戏循环中。
    • 发生这种情况是因为时间戳就是一个时间戳,它没有考虑操作本身执行所需的时间。

这似乎不是您的情况,但是如果您遇到这样的情况,即您正在实施依赖于时间戳的操作,如上节最后一条注释中所述,您要做的是实现一个 delta-time,它使用 nanoTime() 时间戳来获得测量之间经过时间的准确方位,但这也允许要使用的增量。

例如,Delta-time 是制作动画的正确方法。

【讨论】:

    【解决方案3】:

    最后,这是 RHEL 5.4 的一个错误。将客户操作系统升级到 RHEL 5.11 即可解决此问题。

    【讨论】:

    • 不幸的是,我们对实际代码实现的解释都与问题的解决无关,但很高兴听到您已设法修复它,伙计。 =)
    猜你喜欢
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2023-04-06
    • 2023-04-03
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多