2012-04-19 13 views
9

Sono abbastanza nuovo su Node.js e ho una richiesta per un'applicazione che riceverebbe un carico utile di pacchetti UDP e lo elaborerebbe.Come configurare un server UDP node.js molto veloce

Sto parlando di più di 400 messaggi al secondo, che raggiungerebbero qualcosa come 200.000 messaggi/minuto.

Ho scritto un codice per configurare un server UDP (prelevato dai documenti qui http://nodejs.org/api/all.html#all_udp_datagram_sockets in realtà) ma sta perdendo qualcosa attorno al 5% dei pacchetti.

Quello che ho davvero bisogno di sviluppare è un server che otterrebbe il pacchetto e lo invierà a un altro lavoratore fare il lavoro con il messaggio. Ma sembra che il threading in node.js sia un incubo.

Questo è il mio core è:

var dgram = require("dgram"); 
var fs = require("fs"); 
var stream = fs.createWriteStream("received.json",{ flags: 'w', 
    encoding: "utf8", 
    mode: 0666 }); 

var server = dgram.createSocket("udp4"); 
server.on("message", function (msg, rinfo) { 
    console.log("server got: " + msg + " from " + 
    rinfo.address + ":" + rinfo.port); 
    stream.write(msg); 
}); 

server.on("listening", function() { 
    var address = server.address(); 
    console.log("server listening " + 
     address.address + ":" + address.port); 
}); 

server.bind(41234); 
// server listening 0.0.0.0:41234 
+2

Ricorda che i datagrammi, a differenza dei socket TCP, non sono garantiti per il ricevimento. Invece, i datagrammi si concentrano sulla velocità, senza riconoscere singoli messaggi. – skeggse

+0

Sono cose come queste che mi hanno fatto passare a Go e non mi sono mai voltato indietro. –

+0

@AParacha Si prega di elaborare, sto ascoltando: D –

risposta

2

Ti manca concetti, NodeJS non è destinata ad essere multi-thread in termini di dire, le richieste devono essere gestite in un ciclo. Nessun altro thread esiste, quindi non avviene alcun cambio di contesto. In un ambiente multi-core, è possibile creare un cluster tramite il modulo cluster del nodo, ho un post sul blog su questo here.

È possibile impostare i processi padre per eseguire il fork dei processi figli e SOLO i processi figlio devono eseguire il binding a una porta. Il tuo genitore proceses gestirà il bilanciamento del carico tra i bambini.

Nota: Nel mio post sul blog, ho fatto i < os.cpus().length/2; ma dovrebbe essere i < os.cpus().length;

+0

Mi dispiace, penso di non avermi spiegato abbastanza bene, ma il fatto è: come client UDP posso inviare pacchetti UDP da 10k in un secondo, ma il server UDP manca intorno al 5% in un localhost all'ambiente localhost. Ad ogni modo, il mio server è già abbastanza reattivo, risponde a più di 1000 (1kb) messaggi/secondo che è abbastanza per me. – Panthro

+0

Hai scritto "Quello che ho davvero bisogno di sviluppare è un server che otterrebbe il pacchetto e lo invierà a un altro lavoratore che esegue il lavoro con il messaggio.", Ma presumo che tu voglia ridurre il tasso di errore del 5%? Puoi riscrivere la tua domanda? – Mustafa

0

Ho scritto un servizio di inoltro di sapone/xml con una struttura simile, e ha scoperto che le informazioni sarebbe venuto in 2 pacchetti. Avevo bisogno di aggiornare il mio codice per rilevare 2 metà del messaggio e rimetterlo insieme. Questa dimensione di payload potrebbe essere più di un problema HTTP che di un problema di udp, ma il mio suggerimento è quello di aggiungere la registrazione per scrivere tutto ciò che si sta ricevendo e poi passare sopra con un pettine a denti fini. Sembra che tu stia registrando ciò che stai ricevendo ora, ma potresti dover scavare nel 5% che stai perdendo.

Come fai a sapere il suo 5%? se invii di nuovo quel traffico, sarà sempre del 5%? sono sempre gli stessi messaggi persi.

Ho costruito un server UDP per i dati delle chiamate voip/sip usando ruby ​​e Event Machine, e finora le cose hanno funzionato bene. (Sono curioso del tuo approccio di prova però, stavo facendo tutto su netcat, o su un piccolo client rubino, non ho mai fatto messaggi 10k)

Problemi correlati