Question

Mon application RubyOnRails est configurée avec le pack habituel de bâtards derrière la configuration Apache.Nous avons remarqué que l'utilisation de la mémoire de notre serveur Web Mongrel peut devenir assez importante pour certaines opérations et nous aimerions vraiment pouvoir effectuer dynamiquement un redémarrage progressif des processus Mongrel sélectionnés à tout moment.

Cependant, pour des raisons que je n'aborderai pas ici, cela peut parfois être très Il est important que nous n'interrompions pas un Mongrel pendant qu'il répond à une demande, donc je suppose qu'un simple processus d'arrêt n'est pas la réponse.

Idéalement, je veux envoyer au Mongrel un signal qui dit "terminez ce que vous faites, puis quittez avant d'accepter d'autres connexions".

Existe-t-il une technique standard ou une bonne pratique pour cela ?

Était-ce utile?

La solution

J'ai fait un peu plus d'enquête sur la source de Mongrel et il s'avère que Mongrel installe un gestionnaire de signal pour intercepter un processus standard (TERM) et effectuer un arrêt progressif, donc je n'ai pas besoin d'une procédure spéciale après tout.

Vous pouvez voir cela fonctionner à partir de la sortie du journal que vous obtenez lorsque vous tuez un Mongrel pendant qu'il traite une demande.Par exemple:

** TERM signal received.
Thu Aug 28 00:52:35 +0000 2008: Reaping 2 threads for slow workers because of 'shutdown'
Waiting for 2 requests to finish, could take 60 seconds.Thu Aug 28 00:52:41 +0000 2008: Reaping 2 threads for slow workers because of 'shutdown'
Waiting for 2 requests to finish, could take 60 seconds.Thu Aug 28 00:52:43 +0000 2008 (13051) Rendering layoutfalsecontent_typetext/htmlactionindex within layouts/application

Autres conseils

Regardez en utilisant monit.Vous pouvez redémarrer dynamiquement Mongrel en fonction de l'utilisation de la mémoire ou du processeur.Voici une ligne d'un fichier de configuration que j'ai écrit pour un de mes clients.

check process mongrel-8000 with pidfile /var/www/apps/fooapp/current/tmp/pids/mongrel.8000.pid
    start program = "/usr/local/bin/mongrel_rails cluster::start --only 8000"
    stop program = "/usr/local/bin/mongrel_rails cluster::stop --only 8000"

    if totalmem is greater than 150.0 MB for 5 cycles then restart       # eating up memory?
    if cpu is greater than 50% for 8 cycles then alert                  # send an email to admin
    if cpu is greater than 80% for 5 cycles then restart                # hung process?
    if loadavg(5min) greater than 10 for 3 cycles then restart          # bad, bad, bad
    if 3 restarts within 5 cycles then timeout                         # something is wrong, call the sys-admin

    if failed host 192.168.106.53 port 8000 protocol http request /monit_stub
        with timeout 10 seconds
        then restart
    group mongrel

Vous répéteriez ensuite cette configuration pour toutes vos instances de cluster bâtard.La ligne monit_stub est juste un fichier vide que monit tente de télécharger.Si ce n'est pas le cas, il essaie également de redémarrer l'instance.

Note:la surveillance des ressources ne semble pas fonctionner sous OS X avec le noyau Darwin.

La meilleure question est de savoir comment empêcher votre application de consommer tellement de mémoire qu'elle vous oblige à redémarrer les bâtards de temps en temps.

www.modrails.com a considérablement réduit notre empreinte mémoire

Marécageux:

Si un processus est en cours d'exécution, il s'arrêtera progressivement (traitera toutes les requêtes de sa file d'attente, qui ne devrait être que de 1 si vous utilisez un équilibrage de charge approprié).Le problème est que vous ne pouvez pas démarrer le nouveau serveur tant que l'ancien n'est pas mort, donc vos utilisateurs seront mis en file d'attente dans l'équilibreur de charge.Ce que j'ai trouvé réussi, c'est un redémarrage en cascade ou en continu des métis.Au lieu de tous les arrêter et de tous les démarrer (donc mettre les requêtes en file d'attente jusqu'à ce qu'un bâtard soit terminé, arrêté, redémarré et acceptant les connexions), vous pouvez arrêter puis démarrer chaque bâtard séquentiellement, bloquant l'appel pour redémarrer le bâtard suivant jusqu'à ce que le précédent soit sauvegarde (utilisez une véritable vérification HTTP sur un contrôleur /status).Au fur et à mesure que vos bâtards roulent, un seul à la fois est en panne et vous servez sur deux bases de code. Si vous ne pouvez pas le faire, vous devriez afficher une page de maintenance pendant une minute.Vous devriez pouvoir automatiser cela avec Capistrano ou quel que soit votre outil de déploiement.

J'ai donc 3 tâches :cap:deploy - qui effectue la méthode traditionnelle de redémarrage tout en même temps avec un hook qui affiche une page de maintenance, puis la supprime après une vérification HTTP.cap:deploy:rolling - qui fait cette cascade sur la machine (je tire d'un iClassify pour savoir combien de bâtards se trouvent sur la machine donnée) sans page de maintenance.cap déployer:migrations - qui fait la page de maintenance + les migrations car c'est généralement une mauvaise idée d'exécuter des migrations « en direct ».

Essayez d'utiliser :

mongrel_cluster_ctl stop

Vous pouvez aussi utiliser:

mongrel_cluster_ctl restart

tu as une question

que se passe-t-il lorsque /usr/local/bin/mongrel_rails cluster::start --only 8000 est déclenché ?

Est-ce que toutes les requêtes sont servies par ce processus particulier, jusqu'à leur terme ?ou sont-ils avortés ?

Je suis curieux de savoir si toute cette opération de démarrage/redémarrage peut être effectuée sans affecter les utilisateurs finaux...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top