版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010136741/article/details/51590619
转载请标明出处:http://blog.csdn.net/u010136741/article/details/51590619, 本文出自: 柳木木_kylin
【总目录】
【本文简介】
上文我们编写了一个实时获取服务器内存使用情况的demo,单纯从逻辑上来看,这个demo没有问题。但是,现在我们设想一下,如果一个用户连接服务器,那个每秒会执行一次free命令,然后会向客户端发送一次数据,如果有十个用户,那个对于服务器来说,他每秒就不知执行一次free命令,如果是上千,上万个用户连接到服务器呢,那这对服务器的负担是非常大的。所以,我们现在要来优化这个服务器端的代码。
【思路】
大体思路就是将返回数据给用户的定时行为,跟更新内存状态的行为分开:
1.当用用户连接时,开启一个计时器,每秒计算一次内存状态,并且将这个结果保存到一个全局变量中。
2.用户本身还需要开启一个计时器,每秒会去全局变量拉取内存的状态,然后返回给客户端呈现。
3.当所有用户都处于断开连接时,服务器处于挂起状态,不在去获取内存状态的变化,节省了资源浪费。
这样,不管有多少个用户连接到服务器,更新内存的状态的行为只会每秒执行一次。
优化后的服务器代码如下:
//send memory info per second
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({port:8181});
var spawn = require('child_process').spawn;
var mem = {};
var clientMemUpdater = undefined;
function updateMemInfo(){
var free = spawn('free',['-k']);
free.stdout.on('data',function(data){
var strdata = ""+data;
console.log(strdata);
//正则匹配,获取数据
var re = /Mem: *(\d*) *(\d*) *(\d*) *(\d*) *(\d*) *(\d*)/;
var result = strdata.match(re);
if(result.length>0){
mem["total"] = parseInt(result[1]);
mem["used"] = parseInt(result[2]);
mem["free"] = parseInt(result[3]);
//mem["shared"] = parseInt(result[4]);
mem["buffers"] = parseInt(result[5]);
mem["cached"] = parseInt(result[6]);
}
});
}
updateMemInfo();
wss.on('connection',function(ws){
var clientMemSend;
var sendMemUpdates = function(ws){
if(ws.readyState == 1){
ws.send(JSON.stringify(mem));
}
}
clientMemSend = setInterval(function(){
if(typeof clientMemUpdater == 'undefined'){
clientMemUpdater = setInterval(updateMemInfo,1000);
}
sendMemUpdates(ws);
},1000);
sendMemUpdates(ws);
if(typeof clientMemUpdater == 'undefined'){
clientMemUpdater = setInterval(updateMemInfo,1000);
}
ws.on("close",function(){
if(typeof clientMemSend != 'undefined'){
clearInterval(clientMemSend);
}
if(typeof clientMemUpdater !='undefined'){
clearInterval(clientMemUpdater);
clientMemUpdater = undefined;
}
});
});
通过测试,上面的优化对比之前的方案,当客户端不断增加时,内存消耗的区别就会越明显,读者可以自己跑跑代码,体验一下。
【结束语】
在做多次测试过程中,我发现,当我开启多个客户端,然后关闭所有客户端时,内存并没有被释放,直到我手动停止了服务器,内存才会被回收。
我的解决方法是,安装 memwatch,在连接建立 和 关闭 的时候都调用 memwatch.gc() 方法,强制内存回收,可以起到一定的作用。如果大家有更好的解决方案,可以在留言处分享!