3

Java で記述された RMI クライアント アプリケーションがあり、サーバー アプリケーションに定期的に "stay alive" メッセージを送信する必要があります。これを別のハートビート スレッドとして実装しました。このスレッドは、Stay Alive メッセージをサーバーに送信し、Thread.sleep() を使用して 15 秒間スリープします。

スレッドは高優先度に設定されています。

Thread heartbeatThread = new Thread(new HeartbeatRunnable(server));
heartbeatThread.setPriority(Thread.MAX_PRIORITY);
heartbeatThread.start();

ただし、クライアントが実行されているボックスが大量の CPU を使用している場合、ハートビートが欠落していることがわかります。これにより、サーバーはクライアント アプリケーションが停止したと見なします。

メインスレッドに Thread.yield() 呼び出しを追加しましたが、これで問題が解決したわけではありません。

アプリケーションの実行中にハートビートが時間どおりに送信されることを保証する方法はありますか?

4

6 に答える 6

3

あなたは本当にそれを保証することはできません。別のスレッドでハートビートを送信して、ハートビートの送信にかかる時間が遅延に追加されるのを防ぐことができます。また、2つのハートビート間の遅延を、サーバーがクライアントの停止を判断するために使用する時間の半分に設定することをお勧めします。つまり、サーバーが15秒後にクライアントをタイムアウトした場合は、7.5秒ごとにハートビートを送信します。

于 2009-03-24T10:38:17.883 に答える
2

CPUを使用しているプロセスによって異なります。

それがあなたのプロセスではなく、クライアント プロセスが実際に応答しない場合、それはすべての意図と目的に対して有効ではないため、ハートビートを送信しないことが適切です。ボックスの負荷が高すぎてメッセージを処理できないときに、「I'm up and can process messages」というハートビート メッセージが表示されると、誤解を招く可能性があります。

ハートビート メッセージの目的が「このプロセスは実行中ですが、折り返しご連絡するまでに 30 分かかる場合があります」ということである場合は、その処理を行っているすべてのデバイスにそのメッセージをサーバーに送信させます。または、クライアントの応答性に合わせてタイムアウトを設定します。

于 2009-03-24T10:48:11.837 に答える
1

自分で書いた「yield」関数をコードに自由に分散させることで、スレッド化されていない環境でユーザーモードのスレッド化を実装できます。

同様に、ハートビートチェック関数の呼び出しをコード内に自由に分散させることができます。スレッドを放棄し、ハートビートを送信する必要があるかどうかを確認するハートビート関数を定期的に呼び出すだけです。

これは大雑把な解決策ですが、適切な解決策を試しても機能しない場合は、おそらくそれに頼らなければなりません。

実際、できることは、すべての関数呼び出しの先頭にマクロを配置することです。これにより、時刻がすばやくチェックされ、必要に応じてハートビート関数が呼び出されます。

(ああ、Javaにマクロはありますか?私はそうは思いませんが、あなたはその考えを理解しています)。

于 2009-03-28T14:20:50.560 に答える
0

サーバーが稼働中であることをサーバーに通知させたい場合は、開いているソケットを提示する方がよい場合があります。クライアントでは、そのソケットから読み取るだけです。それはブロックされ(サーバーが何も書き込んでいないため)、サーバーが消える/シャットダウンすると、クライアントはサーバーのソケット/ポートが消えたことを示すIOExceptionを受け取ります。

これは、タイムリーなハートビートを提供するサーバーに依存しません。使用するリソースはほとんどなく(サーバー側のTCPポートで、帯域幅はほとんどありません)、サーバー(またはサーバーマシン)が使用できなくなったときにタイムリーに表示されます。

于 2009-03-24T11:39:51.213 に答える
0

おそらく最善の解決策は、Timer のscheduleAtFixedRateを使用することです。これにより、1 つの実行が遅延しても (Java では回避できません)、後続の呼び出しは影響を受けません。

于 2009-03-24T10:49:36.997 に答える