通过http实时远程监控/控制服务器的正确方法

coc*_*cco 7 javascript php ajax node.js

在我的客户端(带有浏览器的手机)上,我想查看服务器CPU,RAM和HDD的统计信息,并从各种日志中收集信息.

我正在使用ajax轮询.

在客户端每隔5秒(setInterval)我调用一个PHP文件:

  1. 扫描包含N个日志的文件夹

  2. 读取每个日志的最后一行

  3. 将其转换为JSON

问题:

  1. 每5秒打开一次新连接.
  2. 多个AJAX调用.
  3. 请求标头(它们也是数据,因此消耗带宽)
  4. 响应头(^)
  5. 使用PHP每5秒读取一次文件.即使没有改变.

最终的JSON数据小于5 KB,但我每5秒发送一次,每次都有标题和新连接,所以基本上每5秒,我必须发送5-10 KB才能获得5 KB 10-20 KB.

60 sec / 5 sec = 12如果我打开应用程序,这些是每分钟新的连接数和每小时约15 MB的流量.

假设我有100个用户,我可以监控/控制我的服务器,在一小时内将有大约1.5 GB的传出流量.

更不用说PHP服务器每5秒读取多个文件100次.

我需要在服务器上每隔5秒读取这些日志的最后几行并将它们写入文件,然后我想将这些数据推送到客户端,只要它已被更改.


使用PHP的SSE(服务器发送事件)

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true){
 echo "id: ".time()."\ndata: ".ReadTheLogs()."\n\n";
 ob_flush();
 flush();
 sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,在与第一个用户建立连接之后,连接保持打开(PHP不是为此而做的),因此我节省了一些空间(请求头,响应头).大多数服务器在我的服务器上的这项工作不允许长时间保持连接打开.

还有多个用户我多次读取日志.(减慢我的旧服务器)我无法控制服务器...我需要使用ajax发送命令...

我需要WebSockets !!!


node.js和websockets

使用node.js,据我所知,我可以做到这一切,而不需要消耗大量的资源和bandwich.连接保持打开,所以没有不必要的标题,我可以接收和发送data.it非常好地处理多个用户.

这就是我需要你帮助的地方.

  1. node.js服务器应该在后台更新,并且如果文件被修改,则每5秒存储一次日志数据.应该用(iwatch,dnotify ...)操作系统

  2. 只有在更改后才能推送数据.

  3. 日志的读取应该在5秒后仅发生一次......所以不是每个用户触发的.


这是我发现的第一个例子......并且修改了..

var ws=require("nodejs-websocket");
var server=ws.createServer(function(conn){

    var data=read(whereToStoreTheLogs);
    conn.sendText(data)// send the logs data to the user 
    //on first connection.

    setTimeout(checkLogs,5000);
    /*
     here i need to continuosly check if the logs are changed.
     but if i use setInterval(checkLogs,5000) or setTimeout
     every user invokes a new timer and so having lots of timers on the server
     can i do that in background?         
    */
    conn.on("text",function(str){
     doStuff(str); // various commands to control the server.
    })
    conn.on("close",function(code,reason){
     console.log("Connection closed")
    })
}).listen(8001);

var checkLogs=function(){
 var data=read(whereToStoreTheLogs);
 if(data!=oldData){
  conn.sendText(data)
 }
 setTimeout(checkLogs,5000);
}
Run Code Online (Sandbox Code Playgroud)

上面的脚本将是通知服务器,但我还需要找到一个解决方案来存储somwhere这些多个日志的信息,并在每次更改时在后台执行该操作.

如何保持bandwich低,还有服务器资源.

你会怎么做?

编辑 Btw.有没有办法来 simultaneosly这个数据发送给所有clinets?

编辑

关于日志:我还希望能够缩放更新之间的时间扩展...我的意思是如果我读取ffmpeg的日志,如果可能的话每秒都会更新...但是当没有转换活动时...我需要每5分钟获得基本的机器信息......等等......

目标: 1.在日志数据的某处读取和存储的高效方式(仅当连接clinets时... [mysql,文件,可以在ram中存储此信息(使用node.js ??)]).2.将数据流式传输到各种客户端的高效方式(同时).3.能够向服务器发送命令..(双向)4.使用网络语言(js,php ...),lunix命令(在多台机器上易于实现的东西)..如果需要,可以使用免费软件.

最好的方法是:

阅读日志,基于当前的活动,到系统内存,并同时和时间可持续流,有一个已经打开的连接,到各种与客户的WebSockets.

我什么都不知道可能会更快.

UPDATE

的node.js服务器启动并运行,采用http://einaros.github.io/ws/ webSocketServer实现,因为它似乎是最快的国家之一.我在@HeadCode的帮助下编写了以下代码来正确处理客户端情况并保持流程尽可能低.检查广播循环内的各种事物.现在推动和客户端处理是一个好点.

var 
wss=new (require('ws').Server)({port:8080}),
isBusy,
logs,
clients,
i,
checkLogs=function(){
 if(wss.clients&&(clients=wss.clients.length)){
  isBusy||(logs=readLogs()/*,isBusy=true*/);
  if(logs){
   i=0;
   while(i<clients){
    wss.clients[i++].send(logs)
   }
  }
 } 
};
setInterval(checkLogs,2000);
Run Code Online (Sandbox Code Playgroud)

但是atm我用一种非常糟糕的方法来解析日志..(nodejs-> httpRequest-> php)..大声笑.经过一些谷歌搜索后,我发现我完全可以直接将linux软件的输出流式传输到nodejs应用程序...我没有检查过...但也许这是最好的方法.node.js还有一个文件系统api,可以读取日志.linux有它自己的文件系统api.

readLogs() (可以是异步)功能仍然是我不是很满意.

  1. nodejs文件系统?
  2. linuxSoftware-> nodejs输出实现
  3. linux文件系统api.

请记住,我需要扫描各种文件夹的日志,然后以某种方式解析输出的数据,这每2秒钟.

ps.:如果logReading系统是异步的,我adde对服务器变量是忙碌的.

编辑

答案不完整.

失踪:

  1. 一种高效的方式来读取,解析和存储日志(linux filesystem api或nodejs api,因此我直接存储到系统内存中)
  2. 解释是否可以将数据直接传输给多个用户.显然nodejs循环通过客户端,所以(我认为)发送多次数据.

btw是否有可能/值得关闭节点服务器如果没有客户端并重新启动apache端的新连接.(例如:如果我连接到apache托管的html文件,脚本会再次启动nodejs服务器).这样做会进一步减少内存泄漏???对吗?

编辑

在对websockets进行了一些实验(一些视频在评论中)后,我学到了一些新东西.Raspberry PI有可能使用一些CPU DMA通道来处理像PWM这样的高频事件......我需要以某种方式理解它是如何工作的.

当使用传感器和类似的东西时,我应该将所有内容存储在RAM中,nodejs已经这样做了?(在脚本内的变量中)

websocket仍然是最佳选择,因为它现在可以从任何设备轻松访问,只需使用浏览器即可.

use*_*342 0

您需要构建一个推送通知服务器。当新数据更新时,所有正在监听的客户端都会收到推送通知。有关更多信息,请参阅此答案:PHP - 推送通知

至于如何更新数据,我建议使用基于操作系统的工具来触发 PHP 脚本(命令行),该脚本将生成一个将 json 文件“推送”到当前正在侦听的任何客户端。任何登录到“listen”的新客户端都将获得当前可用的 json,直到它被更新。

这样,您就不会受到 100 个用户使用 100 个连接的限制,也不会受到每 5 秒轮询服务器的带宽的影响,并且仅在他们需要知道有更新时才获得更新。