Fuite mémoire avec curl et NSS sous RedHat

Depuis plusieurs mois je travaille pour une startup qui fait de la lutte contre la fraude. En deux mots, les clients nous envoient des flux XML et nous leur renvoyons note correspondant à l’indice de confiance de la transaction.

Et, début Janvier nous avons intégré un GROS client. Du genre à faire pâlir les sysadmin. Cela nous à forcer à reconstruire une partie du code, à revoir l’architecture de l’application (qui est au passage devenue une application symfony2).

Le problème à été de faire communiquer la nouvelle partie avec l’ancienne, et comme nous sommes en PHP, ben nous avons opté pour Curl.

Pour chaque score demandé nous avons donc un appel CURL du nouveau code vers l’ancien. Rien d’inquiétant, cela fait partie de l’habituel en PHP.

Sauf que là :

 

Une belle grosse fuite mémoire, entre chaque restart Apache pas moyen de savoir où partait la mémoire. Nous avons d’abord accusé Symfony, l’ORM à assez mauvaise réputation avec des dæmons et Doctrine avoue ne pas être taillée pour absorber de la charge.

J’ai donc mis en place les fix nécessaires: forcer le garbage collector, désallouer la mémoire des objets inutilisés mais rien n’y faisait.

J’ai ensuite testé de lancer mes commandes en –no-debug, de virer les logs mais pas mieux, ma mémoire disparaissait toujours dans les méandres de mon système…

Toute ma RAM foutait le camp, de manière pernicieuse, petit à petit, Mo par Mo jusqu’à arriver à la limite du système, aux alentours du Go de libre – NB: le serveur n’avait pas l’air de souffrir par ailleurs, l’application ne ralentissait pas outre mesure…  

NSS Softoken

Finalement c’est le sysadmin qui à trouvé l’origine, en farfouillant sur le web. Je lui avais parlé peu de temps avant d’une histoire de fuites mémoire dans le CURL, vaguement, j’avais rien pigé à l’article. Il est retombé dessus quelques jours plus tard, et BIM, révélation! Notre fuite mémoire était en fait dû à une faille système, une sombre histoire de NSS (Network Security Services), qui est utilisée par libcurl et qui faisait du cache là où elle ne devrait pas.  C’est assez bas niveau, mais c’est un bug connu sur la version 3.16.0. C’est la version actuelle sur RedHat… Si vous voulez plus de détail je vous invite à lire cet article qui est la source de nos modifications : https://www.splyt.com/blog/2014-05-16-optimizing-aws-nss-softoken

Le fix est assez simple, il suffit d’ajouter une ligne dans la conf’ Apache:

# execute these commands as ‘root’ echo “export NSS_SDB_USE_CACHE=YES” » /etc/sysconfig/httpd service httpd restart

Et voilà, comment retrouver le sourire et plusieurs Go de RAM !