因此,您有一个“中央服务器”,需要向客户端提供心跳机制。嗯,解决方案的一部分很简单,因为您只有一台服务器,这简化了很多事情,因为您不需要处理数据复制、数据同步机制、服务器故障等。你只是希望你的服务器永远不会失败,如果失败了,那就是fatal error.
我的建议是实现一个基于通知的系统(池化是糟糕且丑陋的):而不是让服务器池化客户端,你可以客户端向服务器报告他们的状态每隔 X 秒。这减少了系统的总体过载,它基于“告诉,不要问 http://martinfowler.com/bliki/TellDontAsk.html”。这还允许您为每个客户提供不同的报告时间。
还有一个问题,你要传输什么数据?只要客户还活着?客户端的运行时数据,例如,如果客户端正在下载文件,则完成的工作百分比?环境状态,如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.");
}
}
您应该编写一个服务器来处理所发出的请求,并且足够“智能”,可以在 X 秒后没有来自客户端 Y 的“消息”时调用超时。
这仍然不理想,因为您收集数据并以相同的采样周期发送数据,但通常您希望以非常小的间隔收集数据(例如,每 5 秒收集一次 CPU 使用情况),但只每 30 秒报告一次。
如果您想查看执行此操作的优秀库的优秀代码(这是我们在我公司的项目中使用的代码),请查看J卡塔斯科皮亚 https://github.com/CELAR/cloud-ms/框架代码(只看Agent和Server文件夹,忽略其他)。
关于这个话题有很多话要说,这是基础。欢迎询问!