1

シナリオ

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()?
  • 検出された時間のずれに基づいて、ログのタイムスタンプ値を変更する必要がありますか?
  • 仮想マシンのタイム トラッキング ロスの問題を解決するにはどうすればよいですか?

ホスト OS: RHEL 6.5
ゲスト OS: RHEL 5.4
仮想化プラットフォーム: RHEV 3.4

4

3 に答える 3

1

さまざまなオプションから選択する必要があります

  • より頻繁な時刻同期で正確な時刻を取得できますが、タイムスタンプの順序の不一致が増えます...
  • 時刻同期の頻度を下げるか、完全に無効にすることで時刻の精度を下げますが、タイムスタンプの順序はより一貫しています...

私の知る限り、ハードウェア コンピューターと同じ精度を実現することはできません。

于 2015-08-20T09:36:28.573 に答える
1

currentTimeMillis()はそのままでスレッド セーフですが、OS のクロック タイムに基づいているため、システムのクロック タイムが変更されると不正確になる可能性があり、タイム ドリフト(累積的に不正確になる) が発生しやすくなります。

nanoTime()箱から出してすぐにスレッドセーフではありませんが、代わりにシステムの「アトミッククロック」を使用し(可能な場合*)、システムのクロックの変更の影響を受けず、目的がイベントのタイムスタンプまたはイベントのタイムスタンプを印刷するだけである場合に適しいますそれに依存している*操作のループで使用すると、時間のずれがはるかに少なくなりますが、非常に長い期間にわたって、時間のずれが目立つようになる可能性があります。

  • * - 一部の特定の OS は「アトミック クロック」をまったく提供またはサポートしていません。これらの特定のケースでは、Javaは通常のクロックを使用するしかありません。システムがこれらのいずれかである可能性があると思われる場合は、Google で検索してください。
  • * -ここで「依存する」操作とは、ゲーム ループのように、メソッドまたはアクションが、同じまたは異なるメソッドの最後の呼び出しからの経過時間によってトリガーされるか、それに依存する値を持つ場合を指します。
    • これは、タイム スタンプが単なるタイム スタンプであり、操作自体の実行にかかる時間が考慮されていないために発生します。

これはあなたのケースではないようですが、上記のセクションの最後のメモで説明したように、タイム スタンプに依存する操作を実装している状況に直面したことがある場合は、デルタを実装する必要があります。 -timenanoTime()タイムスタンプを使用して測定間の経過時間の正確な関係を取得しますが、デルタを使用することもできます。

デルタタイムは、たとえばアニメーションを行うための正しい方法です。

于 2015-11-07T22:35:07.397 に答える