> Je comprends pas specialement la question de "quel process".

En fait, je me demandais si c'était le master unicorn ou un de ses 
workers qui segfaultait, d'une part, et si ça arrivait aussi par exemple 
dans des background jobs. J'avoue que je ne soumettrais pas ma phrase 
originale à un concours de clareté d'expression :)

Je n'ai pas eu de mauvaises expériences avec GC pour ma part, "it just 
works". Est-ce qu'il y a dans ton projet des particularités qui peuvent 
influer sur le global space, comme par exemple l'emploi de threads ?


On Wednesday, March 18, 2015 at 11:11:46 AM UTC+1, Florian Dutey wrote:
>
> Merci Olivier. Je n'ai pas precise parce que dans un premier temps, je 
> voulais savoir si quelqu'un avait experimente un probleme similaire (GC qui 
> fait mal son boulot).
>
> Mais puisque tu demandes, je vais ajouter ce que je peux:
>
> Les serveurs (staging et production) sont hostes sur amazon EC2. nous 
> utilisons docker, 2 hosts avec chacun 1 unicorn de 8 workers. L'OS est 
> centOS (3.10.57-57.140.amzn1.x86_64). Pas de nginx mais un HAProxy au 
> sommet qui balance sur les instances. Tout est virtualise donc peu de 
> risque d'erreur materielle.
> Une instance consomme en moyenne 300Mb de RAM, assez stable sur la duree, 
> avec ou sans les erreurs. Au niveau du serveur lui meme, on est tres loin 
> de prendre toute la ram. Sur la longueur, on est stable avec 15Gb 
> d'utilisation (sans pics) sur 30gb dispo.
> Pour rails cache et rack cache, on utilise elasticache (2 instances pour 1 
> appli), on a du redis qui traine un peu partout aussi, postgres (9.3) pour 
> la bdd.
> Les gems avec des extensions natives (sanitize, oj, nokogiri ...) sont 
> toutes a jour, si besoin est de preciser.
>
> Le process unicorn boote sans probleme. Les tests de stress sont assez 
> violents, du coup, la segfault apparait souvent, ce qui fait redemarrer le 
> worker qui la subit a chaque fois. C'est un mecanisme classique de unicorn, 
> pas de gem speciale pour ca.
>
> Merci pour le tips de std_err path au passage, nous n'avons pas de logs 
> pour ca. Il m'a fallu 1 semaine pour decouvrir que c'etait une segfault 
> justement parce que ni newrelic, ni logentries ne le detecte.
>
> Pour voir la segfault, j'ai deploye le code de l'appli dans un repertoire 
> separe sur le serveur d'application. J'ai demarre manuellement unicorn 
> (environnement EC2 donc redis et elasticache peuvent etre contactes et 
> toutes les variables d'env sont set) et lance les stress test pour enfin 
> voir l'erreur.
> Ce repertoire separe est sur une branche a part, donc je peux faire les 
> modifs que je veux, je deploie tres rapidement en faisant juste un pull / 
> unicorn et je peux modifier le code en live (ce qui est proche de 
> l'impossible avec des dockers). Je fais tourner les stress tests a chaque 
> fois. L'erreur apparait tres rapidement en general. 
> Quand elle n'apparait plus, je lance les tests 500x pour etre sur. C'est 
> impossible que 3 millions de requetes (3 en parallele) sur cette action ne 
> genere aucun segfault (20 suffisent en general, 150 obtient une proba de 
> 100%).
>
> Je comprends pas specialement la question de "quel process". On essaie de 
> lire une string qui n'existe plus (GC) et donc n'importe quelle function C 
> va segfault. Ca peut etre :gsub, :initialize_copy (string) ou :dump (json), 
> tout depend quand est ce que GC a nique son monde :p. Dans tous les cas, on 
> reste dans le process unicorn, on n'en sort pas. 
>
> Le 18 mars 2015 17:19, Olivier El Mekki <oelm...@gmail.com <javascript:>> 
> a écrit :
>
>> Hello,
>>
>> Bon courage !
>>
>> Tu ne précises pas ton infrastructure, est-ce que vous êtes sur un seul 
>> serveur ? Plusieurs ? Est-ce un dédié ou des machines virtuelles heroku / 
>> ec2 ? (un pb hardware n'est pas à exclure dans le premier cas).
>>
>> Également, est-ce que tu as une idée du niveau d'usage de ta ram au 
>> moment des fails ? (mais je doute que ce soit le pb, parce qu'une 
>> saturation de la ram se remarquerait pas des problèmes beaucoup moins 
>> isolés et spécifiques).
>>
>> Tu mentionnes que les process unicorn restart en permanence, c'est 
>> généralement le signe d'une app rails qui n'arrive pas à booter. Que disent 
>> les log d'erreur d'unicorn, à ce sujet ? (c'est un fichier de log différent 
>> des logs standard rails, réglé en utilisant la directive `#stderr_path` 
>> dans la conf de unicorn).
>>
>> Comment as-tu isolé les segfaults, et sur quel process se produisent-il ?
>>
>>
>> On Wednesday, March 18, 2015 at 10:02:29 AM UTC+1, Florian Dutey wrote:
>>>
>>> Salut a tous,
>>>
>>> Apres 2 semaines au bord du suicide a buter sur une segfault, je m'en 
>>> viens quemander du partage d'experience parmi vous.
>>>
>>> Background: 
>>>
>>> Nouvelle boite pour moi. Le mois dernier a ete consacrer a migrer notre 
>>> appli de:
>>>
>>> - rails 3.2.19 vers rails 4.2 (en passant par rails 4.0 et 4.1 au milieu 
>>> pour rendre le process plus souple)
>>> - ruby 2.0.0 vers ruby 2.2.1 (en passant par 2.1.5 au milieu)
>>>
>>> Y'a 3 ans de dev dessus, beaucoup de legacy, et la suite sera de 
>>> refactorer tout ca, splitter l'appli en 4 tiers etc..
>>>
>>> Toute la migration s'est plutot bien deroulee, jusqu'a ce qu'on deploie 
>>> en prod et que l'on voie apparaitre des exception sans aucun sens, disant 
>>> que notre data contenait des false et des nil a des endroits completement 
>>> illogiques (et qui disparaissaient immediatement quand on faisait on 
>>> rollback de l'app). Et une derniere qui disait carrement qu'une string 
>>> contenait un nullbyte.
>>>
>>> En meme temps, on a constate sur newrelic que les instance unicorn 
>>> redemarraient en boucle comme des malades, mais sans que la consommation de 
>>> memoire ne bouge. La frequence etant trop elevee pour conclure a un leak, 
>>> ou alors tellement massif qu'on n'aurait pas pu l'eviter en developement.
>>>
>>> Apres 1 semaine a ne pas comprendre ces exceptions, a constater le 
>>> caractere tres aleatoire de leurs apparitions, j'ai fait le postulat que 
>>> c'etait des segfault. Il m'a fallu 2 jours de plus pour les faire 
>>> apparaitre.
>>>
>>> Evidemment le probleme est impossible a reproduire en environnement de 
>>> developement. Meme en demarrant l'appli avec les parametres de production 
>>> en local (ce qui est tres complique de plus a cause des CDN, des serveurs 
>>> de cache etc..).
>>> Nous n'avons toujours pas non plus reussi a le reproduire en console, 
>>> donc nous avons un protocole assez nul pour reproduire l'erreur (spammer le 
>>> serveur sur une action precise).
>>>
>>> Nous avons tout de meme trouve un fix qui nous permet de ne plus avoir 
>>> le probleme, mais ca ne resoud pas l'erreur qui est en dessous et qu'on 
>>> n'arrive pas a identifier.
>>>
>>> Le probleme:
>>>
>>> J'ai d'un cote, un modele (Page) qui a une propriete "content". Il 
>>> s'agit d'un JSON serialize, qui est plutot massif 90% du temps (legacy 
>>> code). 
>>>
>>> Au milieu un controller, qui fait trop de travail
>>> Enfin, plusieurs vues parce qu'on utilise gon + jbuilder et un bon vieux 
>>> template haml (legacy, ya un plan pour switcher en SPA avec Rails::API en 
>>> backend)
>>>
>>> Regulierement (environ 5% du temps), je me mange une segfault quand 
>>> j'essaie d'acceder a la propriete "content" de mon objet Page. La variable 
>>> ne contient plus rien, car elle a ete garbage collected, bien qu'etant 
>>> toujours referencee pourtant.
>>> Le caractere aleatoire etant quand est ce que GC a ete trigger. Il y a 
>>> plusieurs "mauvais endroits" ou il peut etre trigger et cela resulte en des 
>>> exceptions differentes (parce qu'on n'accede pas au meme clefs du hash, 
>>> mais le principe reste le meme).
>>>
>>> Le fix temporaire a ete de desactiver GC pour cette action (et 5 autres 
>>> dans le meme controller qui ont un comportement similaire mais qui n'ont 
>>> jamais fail, par precaution), au moyen de before_action et after_action 
>>> (pas de OobGc donc).
>>> Ca nous permet de faire tourner l'appli en prod mais le code 
>>> "defectueux" le reste. Nous cherchons donc a comprendre et resoudre ce 
>>> probleme une bonne fois pour toutes, mais nous n'avons absolument aucune 
>>> idee de ce qui peut pousser GC a nous virer nos objets.
>>>
>>> Le probleme est present en ruby 2.1.5 et en ruby 2.2.0 (et 2.2.1)
>>>
>>> J'avais deja experimente un probleme similaire d'objets GCed alors 
>>> qu'ils n'auraient pas du (ruby 2.2.0+ only):
>>>
>>> define_method :"#{attr}=" do ... end dans un module pour AR acts_as like.
>>> Quand je sauvais l'objet, AR#save activait le GC et tous mes writers 
>>> disparaissaient de la table des methodes de ma classe (donc 
>>> obj.respond_to?(:attr=) renvoyait false) et je me mangeais des 
>>> NoMethodError. Le fix a ete de virer le : au debut de la string pour en 
>>> faire une string qui sera transformee en symbol immortel par la suite.
>>>
>>> Avez vous deja vu ce genre de choses? Je n'ai trouve personne qui 
>>> pleurait sur google que GC degageait des objets absolument "vivants", alors 
>>> que j'ai experimente le probleme 2x en 2 semaines.
>>> Si vous avez deja vu ca, y'a-t-il une raison evidente que je loupe, 
>>> et/ou un fix solide? 
>>> Je suis aussi preneur de tout conseil qui pourrait m'aider a trouver 
>>> l'origine de l'erreur.
>>>
>>> Merci d'avance :)
>>>
>>  -- 
>> -- 
>> Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" 
>> de Google Groups.
>> Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse 
>> rails...@googlegroups.com <javascript:>
>> Pour résilier votre abonnement envoyez un e-mail à l'adresse 
>> railsfrance...@googlegroups.com <javascript:>
>> --- 
>> Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
>> "Railsfrance".
>> Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
>> concernant, envoyez un e-mail à l'adresse railsfrance...@googlegroups.com 
>> <javascript:>.
>> Pour obtenir davantage d'options, consultez la page 
>> https://groups.google.com/d/optout.
>>
>
>

-- 
-- 
Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de 
Google Groups.
Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse 
railsfrance@googlegroups.com
Pour résilier votre abonnement envoyez un e-mail à l'adresse 
railsfrance-unsubscr...@googlegroups.com
--- 
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
Railsfrance.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, 
envoyez un e-mail à l'adresse railsfrance+unsubscr...@googlegroups.com.
Pour plus d'options, visitez le site https://groups.google.com/d/optout .

Répondre à