java Java心跳设计
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33869092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java heartbeat design
提问by Tata2
I need to implement a heartbeat system on my Java project (3-5 Clients with 1 server for them) but I have some questions.
我需要在我的 Java 项目上实现一个心跳系统(3-5 个客户端和 1 个服务器),但我有一些问题。
1) Do I need to have 2 sockets by clients ? 1 for the heartbeat and 1 to receive normal message for my software
1) 我需要客户端有 2 个套接字吗?1 为心跳,1 为我的软件接收正常消息
2) I saw that in specific case when a client is lagging, the client don't receive a message, how to avoid this ?
2)我看到在特定情况下,当客户端滞后时,客户端没有收到消息,如何避免这种情况?
3) In case of a client disconnect, how to retreive the connection with it ? Without recreate a new socket with it.
3)如果客户端断开连接,如何检索与它的连接?不用重新创建一个新的套接字。
回答by Miguel Cunha
So, you have a "central server" which needs to provide an heartbeat mechanism to the clients. Well, part of the solution is simple since you have only 1 server, which simplifies a LOT since you don't need to deal with data replication, data synchronization mechanisms, server failure, and so on. You just expect that your server never fails and if it fails it's a fatalerror.
因此,您有一个“中央服务器”,它需要为客户端提供心跳机制。嗯,部分解决方案很简单,因为您只有一台服务器,这简化了很多,因为您不需要处理数据复制、数据同步机制、服务器故障等。你只是希望你的服务器永远不会失败,如果它失败了,那就是一个致命的错误。
My suggestion is to implement a system based on notifications (pooling is bad and ugly): instead of having the server pooling the clients, you have the clients reporting to the serverevery X seconds of their state. This reduces the general overload of your system and it's based on the design principle of "Tell, don't ask". This also allows you to have different report times for each individual client.
我的建议是实现一个基于通知的系统(池化既糟糕又丑陋):不是让服务器池化客户端,而是让客户端每隔 X 秒向服务器报告它们的状态。这减少了系统的一般过载,它基于“告诉,不要问”的设计原则。这还允许您为每个客户设置不同的报告时间。
There is one more question, which is what data do you want to transmit? Simply if the client is alive? Runtime data of the client, for example, % of it's job done if the client is downloading a file? Environment status, such as CPU overload, memory usage, network status? Define that, that's the first step.
还有一个问题,你想传输什么数据?如果客户还活着?客户端的运行时数据,例如,如果客户端正在下载文件,它的工作完成百分比?环境状态,如 CPU 过载、内存使用情况、网络状态?定义它,这是第一步。
Talking about the java implementation, you should run your a thread on each of your clients (implementing the Runnable interface). It should look something like this code (this is simplified for the sake of brevity):
谈到 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.");
}
}
You should write a server that handles the requests made and is "smart" enough to call a time-out after X seconds without "news" from client Y.
您应该编写一个服务器来处理所发出的请求,并且足够“聪明”,可以在 X 秒后在没有来自客户端 Y 的“新闻”的情况下调用超时。
This is still not ideal, since you collect data and send it with the same sampling period, but usually you want to collect data at very tiny intervals (collecting CPU usage every 5 seconds, for instance) but only report it every 30 seconds.
这仍然不理想,因为您收集数据并以相同的采样周期发送它,但通常您希望以非常小的时间间隔收集数据(例如每 5 秒收集一次 CPU 使用率),但仅每 30 秒报告一次。
If you want to look at good code of a good library that does this (it's what we've been using to our project at my company), take a look at JCatascopiaframework code (just look at the Agent and Server folders, ignore the others).
如果您想查看执行此操作的优秀库的优秀代码(这是我们一直在我公司的项目中使用的代码),请查看JCatascopia框架代码(只需查看 Agent 和 Server 文件夹,忽略其他)。
There's a lot to say about this topic, this is the basic. Feel free to ask!
关于这个话题有很多话要说,这是基本的。随意问!
回答by Dev01
You could try to take a look at this small framework I made for a project I'd worked one last year. It's focused on a simple implementation and yet a strong feedback about your clients status.
你可以尝试看看我为去年工作的一个项目制作的这个小框架。它专注于一个简单的实施,但对您的客户状态有很强的反馈。
It's based on UDP protocol which sends a payload containg an id, which it can be a MAC address of a NIC or an id chosen and set automatically by you or something else too, that confirms the client being safe and sound.
它基于 UDP 协议,它发送一个包含 id 的有效负载,它可以是 NIC 的 MAC 地址或由您或其他东西自动选择和设置的 id,以确认客户端是安全的。
I think it's kind of cool because it's based on listeners which then receive various kinds of events based on what the heartbeat protocol compute about a client status.
我认为这有点酷,因为它基于侦听器,然后根据心跳协议对客户端状态的计算接收各种事件。
You can find more about it here
I think it's handy to use it with TCP sockets to understand if you are capable or not to send data over your TCP stream. Having continuos feedback on your clients status takes you in a position where you can easily achieve that, for example by saving in some sort of map your client status and check it before sending any kind of data.
我认为将它与 TCP 套接字一起使用来了解您是否能够通过 TCP 流发送数据很方便。对客户状态的持续反馈使您处于可以轻松实现这一目标的位置,例如通过在某种地图中保存您的客户状态并在发送任何类型的数据之前检查它。