Java心跳设计

Java heartbeat design

我需要在我的 Java 项目(3-5 个客户端和 1 个服务器)上实施心跳系统,但我有一些问题。

1) 客户需要2个插座吗? 1 个用于心跳,1 个用于接收我的软件的正常消息

2) 我看到在客户端滞后的特定情况下,客户端收不到消息,如何避免这种情况?

3) 如果客户端断开连接,如何恢复与它的连接?无需使用它重新创建新套接字。

因此,您有一个 "central server" 需要为客户端提供心跳​​机制。好吧,部分解决方案很简单,因为您只有一台服务器,这简化了很多,因为您不需要处理数据复制、数据同步机制、服务器故障等。你只是希望你的服务器永远不会失败,如果它失败了,那就是一个 fatal 错误。

我的建议是实现一个基于通知的系统(池化既糟糕又丑陋):不是让服务器池化客户端,而是让 客户端向服务器报告他们状态的每 X 秒。这减少了系统的一般过载,它基于“Tell, don't ask”的设计原则。这也允许您为每个客户设置不同的报告时间。

还有一个问题,你要传输什么数据?只要客户还活着?客户端的运行时数据,例如,如果客户端正在下载文件,则完成工作的百分比?环境状态,例如CPU过载、内存使用、网络状态?定义那个,这是第一步。

谈到 java 实现,您应该 运行 在每个客户端上创建一个线程(实现 Runnable 接口)。它应该看起来像下面的代码(为简洁起见进行了简化):

public class HeartbeatAgent implements Runnable {

private int DEFAULT_SAMPLING_PERIOD = 5; //seconds
private String DEFAULT_NAME = "HeartbeatAgent";
private HashMap<Integer, Object> values; // <id, value>


public HeartbeatAgent () {
  values = new HashMap<Integer,Object>();

}


private void collect() {
    /** Here you should collect the data you want to send 
        and store it in the hash
    **/

}

public void sendData(){
    /** Here you should send the data to the server. Use REST/SOAP/multicast messages, whatever you want/need/are forced to **/
}

public void run() {
  System.out.println("Running " +  DEFAULT_NAME );
  try {
     while( /** condition you want to stop **/ {
        System.out.println("Thread: " + DEFAULT_NAME + ", " + "I'm alive");

        this.collect();
        this.send();
        // Let the thread sleep for a while.
        Thread.sleep(DEFAULT_SAMPLING_PERIOD * 1000);
     }
 } catch (InterruptedException e) {
     System.out.println("Thread " +  DEFAULT_NAME + " interrupted.");
 }
 System.out.println("Thread " +  DEFAULT_NAME + " exiting.");
}
}

您应该编写一个服务器来处理所发出的请求,并且 "smart" 足以在没有 "news" 来自客户端 Y 的情况下在 X 秒后调用超时。

这仍然不理想,因为您收集数据并以相同的采样周期发送数据,但通常您希望以非常小的间隔收集数据(例如,每 5 秒收集 CPU 使用情况)但每 30 秒才报告一次。

如果您想查看执行此操作的优秀库的优秀代码(这是我们在我公司的项目中一直使用的代码),请查看 JCatascopia 框架代码(只需查看在 Agent 和 Server 文件夹中,忽略其他文件夹)。

这个话题要说的很多,这是基本的。欢迎提问!

你可以试着看看我为我去年工作的一个项目制作的这个小框架。它侧重于简单的实施以及对您的客户状态的强烈反馈。

它基于 UDP 协议,它发送一个包含 id 的有效载荷,它可以是网卡的 MAC 地址或由您自动选择和设置的 id 或其他东西,确认客户端安然无恙。

我认为这很酷,因为它基于侦听器,侦听器然后根据心跳协议对客户端状态的计算接收各种事件。

您可以找到更多相关信息here

我认为将它与 TCP 套接字一起使用可以很方便地了解您是否能够通过 TCP 流发送数据。对您的客户状态进行持续反馈可以让您轻松实现这一目标,例如通过将您的客户状态保存在某种地图中并在发送任何类型的数据之前检查它。