【发布时间】:2015-05-06 16:09:51
【问题描述】:
在我的客户端(带有浏览器的手机)上,我想查看服务器 CPU、RAM 和 HDD 的统计数据,并从各种日志中收集信息。
我正在使用 ajax 轮询。
在客户端每 5 秒 (setInterval) 我调用一个 PHP 文件:
扫描包含 N 条日志的文件夹
读取每条日志的最后一行
将其转换为 JSON
问题:
- 每 5 秒打开一次新连接。
- 多个 AJAX 调用。
- 请求标头(它们也是数据,因此会消耗带宽)
- 响应标头 (^)
- 使用 PHP 每 5 秒读取一次文件。即使没有任何改变。
最终的 JSON 数据小于 5 KB,但是我每 5 秒发送一次,并且每次都有 headers 和新连接,所以基本上每 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);
}
在这种情况下,与第一个用户建立连接后 连接保持打开状态(PHP 不是为此而设计的),因此我节省了一些空间(请求标头、响应标头)。这项工作在我的服务器上工作,但大多数服务器不允许长时间保持连接打开。
还有多个用户,我多次阅读日志。(减慢我的旧服务器) 而且我无法控制服务器...我需要使用 ajax 来发送命令...
我需要 WebSockets!!!
node.js 和 websockets
使用 node.js,据我了解,我可以在不消耗大量资源的情况下完成所有这些操作 资源和带宽。连接保持打开,因此没有不必要的标题,我可以接收和发送数据。它可以很好地处理多个用户。
这就是我需要你帮助的地方。
-
node.js 服务器应该在后台更新,如果文件被修改,则每 5 秒存储一次日志数据。或者操作系统应该使用 (iwatch,dnotify...)
只有在发生变化时才应该推送数据。
日志的读取应仅在 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);
}
上面的脚本将是通知服务器,但我还需要找到一种解决方案来将这些多个日志的信息存储在某个位置,并在每次发生更改时在后台执行此操作。
您将如何保持带宽低以及服务器资源。
你会怎么做?
编辑 顺便提一句。有没有办法将这些数据同时流式传输到所有客户?
编辑
关于日志:我还希望能够缩放更新之间的时间膨胀......我的意思是,如果我读取 ffmpeg 的日志,我会尽可能每秒更新一次......但是当没有转换处于活动状态时。 . 我需要每 5 分钟获取一次基本机器信息……等等……
目标: 1.在某处读取和存储日志数据的高性能方式(仅当客户端连接...[mysql,文件,可以将此信息存储在ram中(使用node.js??)])。 2. 将数据流式传输到各种客户端(同时)的高性能方式。 3.能够向服务器发送命令..(双向) 4. 使用网络语言(js、php...)、lunix 命令(在多台机器上很容易实现的东西).. 如果需要免费软件。
最好的方法是:
根据当前活动将日志读取到系统内存并同时连续地流式传输,并且已经打开连接,通过webSockets连接到各种客户端。
我不知道有什么可以更快的。
更新
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);
但是 atm 我正在使用一种非常糟糕的方式来解析日志.. (nodejs->httpRequest->php).. 哈哈。经过一番谷歌搜索后,我发现我完全可以将 linux 软件的输出直接流式传输到 nodejs 应用程序......我没有检查......但也许这将是最好的方法。 node.js 还有一个文件系统 api,我可以在其中读取日志。 linux有自己的文件系统api。
readLogs()(可以是异步的)功能我仍然不满意。
- nodejs 文件系统?
- linuxSoftware->nodejs 输出实现
- linux 文件系统 api。
请记住,我需要扫描各种文件夹中的日志,然后以某种方式解析输出的数据,并且每 2 秒解析一次。
ps.:如果 logReading 系统是异步的,我将 isBusy 添加到服务器变量中。
编辑
答案不完整。
缺失:
- 一种在某处读取、解析和存储日志的高效方法(linux 文件系统 api 或 nodejs api,因此我直接存储到系统内存中)
- 说明是否可以将数据直接传输给多个用户。 显然 nodejs 通过客户端循环,因此(我认为)发送多次数据。
顺便说一句,如果没有客户端并重新启动 apache 端的新连接,是否有可能/值得关闭节点服务器。 (例如:如果我连接到 apache 托管的 html 文件,则脚本会再次启动 nodejs 服务器)。这样做会进一步减少内存泄漏???对吧?
编辑
在对 websockets 进行了一些试验(一些视频在 cmets 中)之后,我学到了一些新东西。 Raspberry PI 有可能使用一些 CPU DMA 通道来处理诸如 PWM 之类的高频东西……我需要以某种方式了解它是如何工作的。
当使用传感器和类似的东西时,我应该将所有内容存储在 RAM 中,nodejs 已经这样做了?? (在脚本内的变量中)
websocket 仍然是最佳选择,因为它现在基本上可以从任何设备轻松访问,只需使用浏览器。
【问题讨论】:
-
您是否考虑过使用nagios或其他监控工具?
-
您这样做是因为您确实需要监控服务器,还是出于某种学术/娱乐目的?
-
@Keo 我正在监控 ffmpeg 的日志。
-
@Willem D'haeseleer 我喜欢在业余时间学习新东西。如果这就是您的要求,请不要用这个赚钱..我的ubuntu无头服务器在一个带有ffmpeg的虚拟机中...当我最终在转换时正确读取这些日志时,我发现了它需要大量资源......而且我认为我可以编写 js node.js 会很好。
-
免费吗?资源少?更新频率?它是否通过 websockets 输出 json?顺便说一句,我喜欢自己写……使用本机命令……不要使用插件。我不使用 jquery 或类似的东西来使一切变得简单。-
标签: javascript php ajax node.js