45 votes

Fuite de mémoire lors de l'émission de messages avec Socket.IO + Node.js + ZMQ

J'ai trois demandes à parler les uns aux autres. Un serveur websocket (1) qui accepte des connexions à partir de navigateurs, analyse les url de voir quelles sont les données nécessaires, il sert de client s'il en a les données dans la mémoire, si ce n'est la demande à partir d'une autre application appelée "récupérateur" (2). L'outil de récupération reçoit ce travail, les demandes à partir d'une simple API (3) qui retourne les données JSON, et le renvoie à websocker serveur qui le publie aux clients connectés. "Récupérateur" commence alors à vérifier régulièrement si des mises à jour sont à l'url/de l'emploi, et envoie les nouvelles données de serveur websocket comme ils se produisent.

Je utiliser socket.io pour client-serveur websocket de la communication. Serveur Websocket et de l'outil de récupération des pourparlers via ZMQ sockets.

Je test de charge serveur websocket avec 130 connexions. Serveur Websocket publie 160 KO de données à 130 clients à chaque seconde. Au début, il utilise 170mb de RAM pour 130 connexions, mais rapidement cela augmente de 1 GO bien qu'il n'y a pas de nouvelles connexions. Puis socket.io les battements du cœur de signaux commence à échouer, entraînant des pertes de connexion.

J'utilise Nodetime de prendre des tas de clichés. Juste après 130e client se connecte, voici comment la mémoire de l'air:

enter image description here

346 objets mémoire Tampon avec un total de 44MB.

En quatre minutes, le nombre d'objets mémoire Tampon augmente considérablement (de nouveau, sans nouvelles connexions): il y a 3012 avec un total de mémoire de 486MB. Après 10 minutes de plus, il y a 3535 avec un total de mémoire consumpion de 573MB.

J'ai utilisé de Mozilla memwatch à trouver la ligne qui s'ajoute à la mémoire, et ont trouvé à cette fonction:

function notifyObservers(resourceId) {
  var data = resourceData[resourceId];
  io.sockets.in(resourceId).emit('data', data);
}

Si je commente ces lignes, l'utilisation de la mémoire reste le même donc c'est une autre confirmation.

Des idées comment cela peut arriver? J'ai appeler cette fonction à l'intérieur de ZMQ l'abonné de la méthode de prise et je pense qu'elle a quelque chose à faire avec ça.. C'est que le code résultant, si je retire les fonctions et les fusionner en un seul:

// Receive new resource data
const resourceUpdatedSubscriber = zmq.socket('sub').connect('tcp://localhost:5433');
resourceUpdatedSubscriber.subscribe('');

resourceUpdatedSubscriber.on('message', function (data) {
  var resource = JSON.parse(data);

  resourceData[resource.id] = resource.data;

  io.sockets.in(resourceId).emit('data', resourceData[resource.id]);
});

Tout mon code (y compris la charge d'essai) est public et vous pouvez trouver cette web socket serveur ici: https://github.com/denizozger/node-socketio/blob/master/server.js Voir en ligne 138.

J'ai commencé à apprendre le Javascript et le Node.js il y a deux mois donc tout commentaires sont les bienvenus, merci d'avance!

0voto

Prozi Points 844

peut-être essayer d'ajouter

 var resourceData;
 

quelque part dans votre code parce que peut-être votre fuite de mémoire a à voir avec globals

En savoir plus sur les globals ici: https://gist.github.com/hallettj/64478

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X