• [^] # Re: questions (réutilisations, multiplexage, compatibilité)

    Posté par . En réponse au journal Nagios va-t-il quitter le C pour le Python?. Évalué à 2.

    - La plupart sont très liés à Nagios, [...]

    C'est en fait dans ce cadre (toujours pour du Nagios) que je posais ma question ; à savoir : la possibilité de réutiliser un composant pour faire quelque chose d'autres (mais toujours relatif à nagios/shinken). Par ex. re-utiliser le parseur de conf, indépendamment du reste, pour faire un petit outil cli qui valide un changement, ou qui génère un hostexinfo.cfg automatiquement, ou qui fait un diagramme de gantt à partir des timeperiod, ce genre de choses quoi... Depuis j'ai regardé ton code et j'ai ma réponse (qui est: oui, c'est super modulaire, kewl :).

    - [...] Donc tu as tout de même une limite sur le nombre que tu peux lancer en parallèle. Ce nombre est complexe a déterminer suivant le tyype de sonde [...]

    C'est là que le multiplexage et le modèle évènementiel rendent service, justement. Il n'y a rien à déterminer à l'avance, le parallélisme est mis en œuvre par le noyau.

    On peux donner autant de socket qu'on veut à un seul processus (même des centaines de milliers, si on utilise quelque chose de plus scalable que select(2), cf. haproxy par ex.), et ce processus travaille dès que l'une d'elles a des données dispos à lire. Au plus fort de la charge, le processus passe tout son temps (il utilise un cœur de cpu à plein) à faire les vrais traitements des données utiles en transit, aussi vite qu'il peut. Lorsqu'il n'y a rien à lire ou écrire, le processus dort. Dans tout les cas, et quelque soit le nombre de sockets dont il est responsable, le processus ne consomme que les ressources (ram et cpu) nécessaires au vrais traitements qu'il doit faire.

    Un exemple : c'est pour ces raisons (une mainloop événementielle coté lighttpd et nginx vs. des pools de workers, threads ou forks, un pour chaque requète simultanée coté apache) que nginx et lighttpd ne sont pas affectés par le récent "slowloris", alors qu'apache s'écroule

    Pour les mêmes raisons, lorsque plusieurs hôtes ne répondent pas aux requêtes, les plugins classique mais parallélisés vont sans doute occuper des ressources (x poller en attente + x * le plugin lui-même) jusqu'aux timeouts, et donc ralentir les autres traitements (si on essaie de maintenir un nombre constant/max de checks en cours) ou mettre le serveur de monitoring à genoux (si on ne limite pas), au moment ou justement on a besoin de monitoring précis et réactif parce qu'il y a des soucis sur le réseau.

    De même, un processus dédié peut certainement gérer sans charge aucune quelques milliers de raw sockets pour envoyer/recevoir des pings en natif (sans "popen('/bin/ping'...)", mais il faut que le processus soit root ou la capabilty CAP_NET_RAW...) et avoir un résultat de check_host_alive à la seconde près sur un large parc. Dans le genre de http://gitorious.org/poe-component-client-ping .

    Des docs pythoniques sur le sujet:
    http://squirl.nightmare.com/medusa/async_sockets.html
    http://docs.python.org/library/asyncore.html
    http://docs.python.org/library/asynchat.html


    - Je n'ia pas encore trouvé de méthode facile çà utiliser pour l'utilisateur (il "décrit" le plugin à utilsier dans la conf de sa commande? On se base sur une reconnaissance de la commande en expression régulière?)

    C'est vrais, je ne vois pas non plus de moyen élégant pour substituer l'exécution des plugins connus/réimplémentés par une version ad hoc...
    - Soit, comme tu dit, faire la substitution lorsqu'on reconnait un nom de plugin en arg d'une check_command... mais le parsing, berk
    - Soit de façon déclarative (eg. "check_command check_tcp_shinken"). Moindre suprise, mais divergence avec une conf nagios brute.
    - Soit de façon déclarative, dans un fichier de conf distinct et propre à shinken (genre shinken-specific.cfg), surchargeant la définition des plugins classiques. La aussi, ca fait une nouvelle divergence avec la conf nagios brute.
    - Soit en fournissant un exécutable effectif (/usr/bin/check_tcp), qui au lieu d'effectuer le check lui-même, se contente de donner l'ordre de le faire au poller en charge des sockets, et retourne un code "maison" (qui signifierai : je n'ai pas le résultat, attends que le poller te le donne) (et/ou effectuerai le check lui même si et seulement si il n'a pas réussi à déléguer le check à un poller). Mais on ne s'affranchit alors pas de la surcharge inutile des fork()/exec()/popen() & reap, et puis c'est tarabiscoté ;)

    Rien de totalement naturel et clean, effectivement.

    - Le fait de dédier des pollers je ne suis pas sûr, car un poller pourrait avoir plusieurs types de workers

    Effectivement, j'avais cru que les pollers se chargeaient de lancer les actions (pas vu le worker.py).

    Désolé d'amener la discussion sur ces petits détails ; shinken semble déjà un super progrès par rapport à l'architecture de nagios :). La possibilité de faire tourner plein de checks classiques légers (tcp, http, udp, icmp) a intervalles très fréquents sans saturer le serveur de monitoring est peut-être un besoin plus perso qu'autre chose (mon serveur de monitoring fait tourner plein de trucs gourmands en plus de nagios, j'ai très peu de checks lourds en perl ou autre, et j'aimerai être avertis des problèmes plus vite qu'actuellement ...).