node.js http server how to get connections count - javascript

I'm using node as a http server with the following code:
http.createServer(function(req, res) {}).listen(8181);
I'm looking for a simple way to monitor a node js http server from within the same process. For me it would be enough to have a own function which just outputs the current resource usage and connection count as json. For now I don't need deep measuring or real time performance monitoring.
What are the key performance indicators for a node http server and is it possible to get them from node? If yes how?
What you think of the folling kpi's:
Connection Count
CPU Usage
Ram Usage
Just need to know which variables/functions I need to get the data?
Thx I really appreciate your help

You can get the amount of connection using a built in function of NodeJS. Check getConnections. Bellow an example how to use it:
var server = http.createServer(app);
server.getConnections(function(error, count) {
console.log(count);
});
I hope this is what you were looking for :)

You need something like this:
var count = 0;
http.createServer(function(req, res) {
count++;
res.on('finish', function () {
//setTimeout(function () {
count--;
//}, 60000);
}).on('close', function () {
count--;
});
}).listen(8181);
With setTimeout() you can get the active connections in the last 1 minute.
see http://nodejs.org/api/os.html#os_os_cpus for CPU usage
see http://nodejs.org/api/process.html#process_process_memoryusage for memory usage

scribbles is a logging module I created.
You can just drop in you project and get CPU, Mem & Net out of the box + more some other handy flags & metrics.
Checkout the performance-monitoring part.
To use:
const scribbles = require('scribbles');
scribbles.config({
dataOut:console.log
})
setInterval(function(){
scribbles.status();
}, 5000);
// This will give you a performance snapshot every 5 seconds.
You get:
network: Networking info
port: listening on this Port
connections: number of current established connections
state: the state of the services. e.g. "up", "blocking"
cpu: CPU info
cores: number of available cores
model: description of the processor
speed: MHz frequency speed
percUsed: load on process as percentage
percFree: available on process as percentage
sys: System info
startedAt: when it's system was started
arch: platform architecture. e.g "x64"
platform: the operating system platform
totalMem: the total megabytes of memory being used
freeMem: the total megabytes of memory free
usedMem: the total megabytes of memory being used
process:
percUsedCpu: the percentage of processing power being used by this process
percFreeMem: the percentage of memory being used by this process
usedMem: the total megabytes of memory being used by this process
startedAt: when it's process was started
pTitle: the current process title (i.e. returns the current value of ps)
pid: the ID of the process
ppid: the ID of the current parent process
user: node the name of the user who started node
vNode: version of node

Related

How do I know I've hit the threads limit defined in Node?

I have limited the size of the thread pool to 25.
process.env.UV_THREADPOOL_SIZE = 25;
How can one know that all the threads are exhausted at run time?
Is there any way to find that all the define threads are exhausted during
a new request?
I'm using Native Abstractions for Node.js (NAN) to call C++ functions. For every request to C++ Nan::AsyncQueueWorker is created. Here I want to find if the thread limit is exhausted and then add a safety factor.
Are you looking implementation in nan or js?
In Nan impl:
You have to do it manually. Maintain a map where key is int and value as workAsyn. Push at every call and delete when workAsyn complete. Do this for every request.
Compare the size of map with your thread limit defined.
I analyzed nan and libuv sources. Unfortunately, now there's no way to get the number of used threads. If only to add this feature yourself.
It looks like this cluster module might be able to help...
var cluster = require('../')
,http = require('http');
var server = http.createServer(function(req, res){
res.writeHead(200);
res.end('Hello World');
});
var workerCount = 0;
cluster(server)
.listen(3000)
.on('worker',()=> {
workerCount++;
console.log('workerCount',workerCount)
})
.on('worker killed',()=> {
workerCount--;
console.log('workerCount',workerCount)
})
Also appears to be able to access the worker count directly from master with the REPL "telnet" plugin...
http://learnboost.github.io/cluster/docs/stats.html
Docs

Socket.io stop working after seconds, many .emit()?

I'm doing a 2d game where connected people walk the map, so I need a quick update of where people will be.
every 17 milliseconds (17 because is 60 fps (1000/60)) I send a multidimensional array where all the characters on the map are.
The problem is that, after a few seconds that 1 person connects to the server, it (the server) simply stops sending console.log that I programmed and does nothing else, no warning appears and does not respond if you try to access it directly over the internet.
Is it an overload that it suffers? I tried to increase the delay to 500 milliseconds and even so when 2 people entered it already crash.
If it's really an overhead, what would I have to do to make my game work?
Observation: The character's move system, the client asks the server to change the character's position in the array according to the direction of the arrow.
code:
Server.js:
let jogadoresSala = [[]];
io.on('connection', socket=>{
//codigo que é executado quando uma pessoa conecta
socketIds.push(socket.id);
pessoasConectadas++;
console.log("nova conexão : " + socket.id);
socket.emit('voceEstaConectado', pessoasConectadas);
socket.join('jogadores');
if(pessoasConectadas == 1){
jogadoresSala[0] = [Math.floor(Math.random() * 300),
Math.floor(Math.random() * 300), socket.id];
setInterval(function () {
console.log('sending..');
io.in('jogadores').emit('sincronizacao', jogadoresSala);
}, 17); //where is the loop
} else {
jogadoresSala.push([Math.floor(Math.random() * 300),
Math.floor(Math.random() * 300), socket.id]);
}
}
cliente.js
(work for seconds, if the client does not move, it can reach within minutes);
socket.on('sincronizacao', posicoesPersonagens => {
console.log(posicoesPersonagens);
var key = [];
for (let i = 0; i < posicoesPersonagens.length; i++) {
personagem.setarPosicao(posicoesPersonagens[i][0], posicoesPersonagens[i][1]);
}
})
picture of the game:
One problem is that you have this code:
setInterval(function () {
console.log('sending..');
io.in('jogadores').emit('sincronizacao', jogadoresSala);
}, 17); //where is the loop
inside of:
io.on('connection', ...)
That means that you start a new interval that is broadcasting to all jogadores every 17ms every time the first user connects. I know you're trying to test for doing this only on the first user, but if you go 1 user, 0 user, 1 user, 0 user, then you will start this interval multiple times.
So, for starters, you need to move the setInterval() outside the io.on('connection', ...) callback. Just put it at the top level once your server is started. If there are no clients connected, then it won't have anything to do because there will be no connections in the jogadores room, so no problem.
Then, 17ms (60fps) is probably too fast for a real world scenario over the internet with lots of clients. What speed will work will depend upon your server configuration, your ISP and how many clients you expect to support with one server and you will ultimately have to understand your limits with testing at scale on your actual hardware. Real-time client-server multi-user gaming is not a trivial endeavor. There are lots of tricks that real-time multi-user gaming systems use to try to prevent lag and have timely updates. Going into the details of all the things that can be done is beyond the scope of an answer here. But, suffice it to say that you don't just power your way through it by trying to send 60fps updates to the client. That doesn't really work. You will need to make your user experience work at a far slower update rate.

node js clustering is repeating the same task on all 8 processes

I've been trying to enable clustering in my node js app. Currently I use this snippet to enable it:
var cluster = require('cluster');
if (cluster.isMaster) {
// Count the machine's CPUs
var cpuCount = require('os').cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
cluster.fork();
}
// Listen for dying workers
cluster.on('exit', function () {
cluster.fork();
});
}
And basically my code performs writes to a Firebase database based on conditions. The problem is that the writes are occurring 8 times each, rather than one worker just taking care of one write task, it seems that all threads are performing all tasks. Is there a way to avoid this? If so, can someone point me in the direction of some resources on this? I can't find anything on google for using Firebase with node js clustering. Here is an example of the way one of my functions work (ref is my firebase reference):
ref.child('user-sent').on('child_added', function(snapshot) {
var message = snapshot.child('message');
payload['user-received/'] = message;
ref.update(payload); // this occurs once for each fork so it updates 8 times
});
If you're spawning 8 threads and each thread attaches a listener on the same location (user-sent), then each thread will fire the child_added event for each child under that location. This is the expected behavior.
If you want to implement a worker queue, where each node under user-sent is only handled by one thread, you'll have to use a work-distribution mechanism that ensures only one thread can claim each node.
The firebase-queue library implements such a work claim mechanism, using Firebase Database transactions. It's been used to scale to a small to medium number of workers (think < 10, not dozens).

What caused process.hrtime() hanging in nodejs?

Here is the code:
var process = require('process')
var c = 0;
while (true) {
var t = process.hrtime();
console.log(++c);
}
Here is my environment:
nodejs v4.2.4, Ubuntu 14.04 LTS on Oracle VM virtualbox v5.0.4 r102546 running in Windows 7
This loop can only run about 60k to 80k times before it hangs. Nothing happens after that.
In my colleague's computer maybe 40k to 60k times. But shouldn't this loop continues forever?
I was first running a benchmark which tests avg execution time of setting up connections, so I can't just get the start time at first then end time after everything finished.
Is this related to the OS that I use?
Thanks if anyone knows the problem.
==========================================================
update 2016.4.13:
One day right after I raised this question, I realized what a stupid question it was. And it was not what I really want to do. So I'm gonna explain it further.
Here is the testing structure:
I have a node server which handles connections.Client will send a 'setup' event on 'connect' event. A Redis subscribe channel will be made at server side and then make some queries from db, then call client's callback of 'setup' event. Client disconnect socket in 'setup' callback, and reconnect on 'disconnect' event.
The client codes use socket.io-client to run in backend and cluster to simulate high concurrency.
Codes are like these:
(some of the functions are not listed here)
[server]
socket.on('setup', function(data, callback) {
queryFromDB();
subscribeToRedis();
callback();
}
[client]
var requests = 1000;
if (cluster.isMaster) {
for (var i = 0; i < 100; ++i) {
cluster.fork();
}
} else {
var count = 0;
var startTime = process.hrtime();
socket = io.connect(...);
socket.on('connect', function() {
socket.emit('setup', {arg1:'...', arg2:'...'}, function() {
var setupEndTime = process.hrtime();
calculateSetupTime(startTime, setupEndTime);
socket.disconnect();
}
}
socket.on('disconnect', function() {
if (count++ < requests) {
var disconnectEndTime = process.hrtime();
calculateSetupTime(startTime, disconnectEndTime);
socket.connect();
} else {
process.exit();
}
}
}
At first the connections could only make 500 or 600 times. Somehow I removed all the hrtime() codes, it made it to 1000 times. But later I raised the number of requests to like 2000 times (without hrtime() codes), it could not finish again.
I was totally confused. Yesterday I thought it was related to hrtime, but of course it wasn't, any infinite loop would hang. I was misled by hrtime.
But what's the problem now?
===================================================================
update 2016.4.19
I solved this problem.
The reason is my client codes use socket.disconnect and socket.connect to simulate a new user. This is wrong.
In this case server may not recognize the old socket disconnected. You have to delete your socket object and new another one.
So you may find the connection count does not equal to disconnection count, and this will prevent our code from disconnecting to redis, thus the whole loop hang because of redis not responsing.
Your code is an infinite loop - at some point this will always exhaust system resources and cause your application to hang.
Other than causing your application to hang, the code you have posted does very little else. Essentially, it could be described like this:
For the rest of eternity, or until my app hangs, (whichever happens first):
Get the current high-resolution real time, and then ignore it without doing anything with it.
Increment a number and log it
Repeat as quickly as possible
If this is really what you wanted to do - you have acheived it, but it will always hang at some point. Otherwise, you may want to explain your desired result further.

Arduino Webserver Update

I have a small tidbit of code for my webserver on my arduino connected to an ethernet shield:
client.println("<html><head><title>ArduServ</title></head><body>");
client.print("Current Temperature: ");client.println(getTMP());
client.println("<form method=get>Input:<input type=text size=25 name=inp><input type=submit value=submit></form>");
client.println("</body></html>");
Is there a way I can update the temperature using javascript so that I don't have to redraw the page every second? I can just change the temperature?
I personally would not use the Arduino as an HTTP server for a couple of reasons.
Performance - as a micro controller, you have limited resources. Serving all of the headers and content can be expensive if you want the interaction to be real time.
Manageability - as I'm sure you're aware, it's really frustrating having to manage the source of the web page through strings in double quotes on multiple lines like that.
The Solution
I've found that the most effective way to make a web controller interface for an Arduino is to host the page somewhere on your computer locally or even on a server if you have one. Then, make the Arduino a web socket server instead of HTTP server.
This will allow you to easily communicate using the WebSocket class in JavaScript, while not having to worry about the overhead of hosting the web content.
I've used this web socket server implementation for Arduino and it works great.
Here's a basic example based on what you showed us.
Arduino
Assuming ethernet is an EthernetServer, and socket is a WebSocketServer.
// initialize the ethernet and socket server in setup() here ...
void loop(void)
{
EthernetClient client = ethernet.available();
if (client.connected() && socket.handshake(client))
{
while (client.connected())
{
String response;
// add the temperature to the response
response += getTMP();
// send the response to the JavaScript interface
socket.sendData(response);
// update every 250 milliseconds
delay(250);
}
}
// wait to let the client fully disconnect
delay(100);
}
JavaScript
// assuming you have something like <div id="temperature"></div> in the document
var temperature = document.getElementById('temperature');
// whatever IP that was assigned to the EthernetServer
var ip = '192.168.0.99';
var socket = new WebSocket('ws://'+ ip);
socket.onmessage = function(e) {
// update the temperature text
temperature.innerHTML = e.data;
};
You can find more information about JavaScript web sockets here.

Categories

Resources