web-dev-qa-db-fra.com

Pourquoi CELERY_ROUTES a-t-il à la fois une "file d'attente" et une "clé de routage"?

D'après ce que je comprends de l'AMQP, les messages ne comportent que les composants suivants:

  1. Le corps du message
  2. La clé de routage
  3. L'échange

Les files d'attente sont attachées aux échanges. Les messages ne peuvent avoir aucune connaissance des files d'attente. Ils envoient simplement des messages dans un échange, puis, en fonction du type d’échange et de la clé de routage, les messages sont acheminés vers une ou plusieurs files d’attente.

Dans Celery, la méthode recommandée pour l'acheminement des tâches consiste à utiliser le paramètre CELERY_ROUTES. Dans les documents, CELERY_ROUTES est ...

Une liste de routeurs ou un seul routeur utilisé pour router les tâches vers des files d'attente . http://celery.readthedocs.org/fr/latest/configuration.html#message-routing

Et cela inclut un exemple ...

Pour router une tâche vers la file d'attente feed_tasks, vous pouvez ajouter une entrée dans le fichier Réglage CELERY_ROUTES:

CELERY_ROUTES = {
    'feeds.tasks.import_feed': {
        'queue': 'feed_tasks',
        'routing_key': 'feed.import',
    },
}

Mais attendez une minute - Selon l’AMQP, les messages ne sont livrés qu’avec une clé de routage! Qu'est-ce que la "file" fait là?

De plus, il y a cette notion de file d'attente par défaut. Si vous appelez une tâche qui n'est pas interceptée par CELERY_ROUTES, elle retombe à CELERY_DEFAULT_QUEUE. Mais encore une fois - dans AMQP, les messages ne connaissent pas les files d'attente. Cela ne devrait-il pas être la clé de routage par défaut?

28
Adam Easterling

Il est vrai que sur Celery il y a un peu de confusion quand vous allez dans les files d'attente, une chose à garder à l'esprit est que le paramètre queue fait référence à un objet de file d'attente Celery Kombu et non directement à une file d'attente AMQP, vous pouvez le comprendre en lisant ceci extrait des documents . Bien sûr, le fait que le céleri crée la file d'attente et que l'échange avec le même nom est à l'origine de la confusion du paramètre d'utilisation de la file d'attente . Toujours dans les documents, vous pouvez le lire. paragraphe:

Si vous souhaitez ajouter une autre file d'attente mais sur un autre échange, spécifiez simplement un échange personnalisé et un type d'échange:

CELERY_QUEUES = (
    Queue('feed_tasks',    routing_key='feed.#'),
    Queue('regular_tasks', routing_key='task.#'),
    Queue('image_tasks',   exchange=Exchange('mediatasks', type='direct'),
                       routing_key='image.compress'),
)

Ainsi, de cette manière, vous pouvez lier 2 files d’attente différentes sur le même échange . Après l’acheminement de la tâche en utilisant uniquement l’échange et la clé, vous pouvez utiliser la classe Routeurs.

class MyRouter(object):

    def route_for_task(self, task, args=None, kwargs=None):
        if task == 'myapp.tasks.compress_video':
            return {'exchange': 'video',
                    'exchange_type': 'topic',
                    'routing_key': 'video.compress'}
        return None

Plus ici http://celery.readthedocs.org/en/latest/userguide/routing.html#routers

16
Mauro Rocco

Le point d’avoir la file d’attente déclarée ici est que le céleri crée ces files d’attente et configure la configuration avec RabbitMQ. 

Pour un client AMQP de niveau inférieur, vous devez d'abord déclarer la file d'attente, puis l'échange, puis enfin lier l'échange à la file d'attente. Plus tard, lors de la publication de messages, il vous suffit d’envoyer des messages à l’échange. 

Il semble que le céleri utilise cette structure pour le faire automatiquement. 

0
olekeh