REX sur 5 ans d'élevage de lapins

Bonjour,

Ulrich Lusseau - www.mon-code.net

    11 ans d'XP pro

    PHP depuis 2002

    Sf depuis 2008

    Éleveur de lapin depuis 5 ans
    Baby devops

RabbitMQ intro

Publication dans une queue

Abus de language

On publie dans un exchange avec une routing key. Ces 2 éléments sont utilisés par RabbitMQ  pour délivrer le message dans une/des queue(s).

Premier contact

Refonte d'un projet de synchronisation de calendrier

App -> SOGo : temps "quasi réel" avec RabbitMQ
SOGo -> App : crontab

Solution retenue

Config RabbitMQ

2 instances

1 vhost pour le projet

1 exchange type direct

6 queues

Worker

Projet Symfony 2 dédié

Lib php amqp

RabbitMQBundle

Planification Worker

Aucune idée de la charge

Application utilisée aux heures de bureau

Cron ou Deamon

Planification Worker

Cron :

 - Programmé toutes les 5 minutes

 - Consommation 1000 messages ou TTL 5 minutes

 

Autonomie vis à vis de l'infogérant

Facile à appréhender pour l'équipe

Plus simple à arrêter qu'un daemon

Payload

Format JSON

Plus petit possible

Headers dans le payload pour faciliter le debug

{
    "headers": {
        "date": "2018-05-18 14:00:00",
        "exchange": "afup",
        "routingkey": "phptour2018"
    },
    "body": {
        "event_id": 42
    }
}

Premiers problèmes

Mauvaise gestion d'erreur

Erreur mal gérée, fait planter le worker

+

Stratégie du worker : message NAK et remis en queue

=

boucle infinie

Queue d'erreur

Catcher les erreurs dans le worker

Publier les messages dans une queue d'erreur

ACK les messages

Répartition de charge

Évolution de l'archi

Création d'un cluster

RabbitMQ indispo

Serveur de cron planté
Problème réseau

 

Impossible de publier dans RabbitMQ

Fallback Publisher

Si RabbitMQ indispo alors envoie du message par mail

Un matin : 10 000 mails

Fédération

Mauvais routing

RoutingKey ne correspond pas entre l'application et la déclaration dans RabbitMQ

 

Perte du message sans aucune alerte

Alternate Exchange

Utilisation de l'option Alternate-exchange

Création d'un exchange type Fanout avec sa queue.

Utilisation d'une Policy pour appliquer un Alternate-Exchange sur tous les exchanges existants.

Auto-scale des workers

Le monitoring est important pour avoir une vision de l'utilisation et la tendance :

 - nombre message/queue

 - taille des queues

 

Besoin d'absorber ponctuellement des grosses charges

API du plugin Management

Wrap des workers avec un appel sur l'API du plugin management pour connaître le nombre de messages dans la queue et le nombre de workers en cours

 

Augmentation de la fréquence du cron des workers

Ce qu'on a oublié !

Mettre en place de l'alerting

 

0 message publié en x heures

 

Nombre message > Y dans les queues

Le projet est un succès

Nouveaux projets

Volonté de mutualiser le code entre les projets

Swarrot

Les nouveaux projets

Gains :

   Stack de processor (decorator) = plus modulaire

   Lib + Bundle plus facile a intégrer dans du legacy

 

Pertes :

   Pas de configuration de RabbitMQ (queue, exchange...)

   Impossible de connaître le nombre de consumer (PR#169)

Swarrot processor

Ack message, exception catcher, max message, memory limit ...

Gestion du retry

Un traitement qui échoue a instant t peut réussir à un instant t+x

 

Mixe des options : TTL, DLX et DLK

Gestion du retry

Attention au retry infini :

    - mettre le nombre de retry dans le payload

    - utiliser X-DEATH dans les headers du message

Gestion d'erreur V2

Engorgement de la queue d'erreur

Beaucoup de faux positif

Nécessite beaucoup de temps à dépiler

Nouvelle stratégie

MySQL has gone away :

    NACK/requeue du message et fin du worker

 

API qui ne répond pas :

    ACK du message et publication pour les mettre en queue  de retry 

 

Autres erreurs :

    ACK du message et publication pour les mettre en queue d'erreur

 

Queue d'erreur

Tous les messages arrivent dans la même queue d'erreur

 

Nécessite beaucoup de temps pour dépiler les messages

 

Multiplication des queues d'erreur

Une queue d'erreur dédiée par queue "applicative"

 

Plus facile pour le monitoring et l'alerting

Organisation

1 vhost / projet

1 seul utilisateur

+90 queues

Les mêmes instances RabbitMQ pour tous = spof

Si c'était à refaire

1 vhost / domaine fonctionnel du projet

1 utilisateur / projet / vhost

1 instance|cluster RabbitMQ / projet

Gestion configuration

CLI nécessite les droits root ou config sudo

Plugin Management un peu laborieux pour la gestion des queues, exchanges, ...
CLI du plugin management nécessite un accès SSH et tout aussi laborieux que l'UI

Rabbit-setup

Création d'un outil dédié, à destination des dévs

Call de l'API du plugin Management

Fichier de conf Yaml

Projet open source : https://github.com/metfan/rabbit-setup

Rabbit-setup config

rabbit_setup:
    connections:
        default:
            user: guest
            password: guest
            host: 127.0.0.1
            port: 15672
    vhosts:
        collector: #vhost name
            connection: default
            policies:
                AE:
                    pattern: "collector"
                    apply-to: exchanges
                    definition: {alternate-exchange: unroutable}
            exchanges:
                unroutable:
                    type: fanout
                collector:
                    type: direct
            queues:
                unroutable:
                    bindings:
                        - { exchange: unroutable, routing_key: null }
                picture:
                    bindings:
                        - { exchange: collector, routing_key: picture}

Rabbit-setup CI

Commande de validation de la config

Commande de création de la config

Un peu de fun

Scheduler

Projet de signature électronique

3 queues de retry

Session de signature valide 14 jours

1 queue classique pour checker le status

Pendant les 23 heures suivantes :

    1 queue de retry avec un TTL de 30 minutes

Jusqu'à expiration de la session :

    1 queue de retry avec un TTL de 1h

Pendant la première heure :

    1 queue de retry avec un TTL de 5 minutes

Le mega worker

SRP pour les workers

Questions ?