Java心跳设计

标签 java sockets serversocket heartbeat

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

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

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

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

最佳答案

因此,您有一个“中央服务器”,需要为客户端提供心跳​​机制。好吧,部分解决方案很简单,因为您只有一台服务器,这简化了很多,因为您不需要处理数据复制、数据同步机制、服务器故障等。您只是期望您的服务器永远不会出现故障,如果出现故障,则会出现致命错误。

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

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

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

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.");
}
}

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

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

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

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

关于Java心跳设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33869092/

相关文章:

java - Android AppUpdateManager 未初始化自动更新

java.lang.OutOfMemory错误: Java heap space creating a long list of Myclass

java - 将属性传递给 Spring 上下文

html - 如何使用 C 从 http 下载文件?

c# - 反序列化不会转移我的 bool 值

sockets - 无限循环监听套接字

java - 使用 Spring CloudVault 的 Spring okta oauth2 属性

python - 如何在Python中找到LAN的广播地址?

Java:如何使用 ServerSocket 和 Socket 正确关闭套接字连接

java - 是否可以让多个线程监听同一个 DatagramSocket?