2012-05-22 31 views
6

Django ve Kereviz kullanıyorum ve birden çok sıraya yönlendirmeyi kurmaya çalışıyorum. Bir görevin routing_key ve exchange (görev dekoratöründe veya apply_async()'u kullanarak) belirttiğimde, görev aracıya eklenmez (Kombu, MySQL veritabanıma bağlanır).Django & Kereviz - Yönlendirme sorunları

Görev dekolayısındaki sıra adını belirtirseniz (bu, yönlendirme anahtarının yok sayılacağı anlamına gelir), görev düzgün çalışır. Yönlendirme/değişim kurulumuyla ilgili bir sorun gibi görünüyor.

Sorun ne olabilir?

:

INSTALLED_APPS = (
    ... 
    'kombu.transport.django', 
    'djcelery', 
) 
BROKER_BACKEND = 'django' 
CELERY_DEFAULT_QUEUE = 'default' 
CELERY_DEFAULT_EXCHANGE = "tasks" 
CELERY_DEFAULT_EXCHANGE_TYPE = "topic" 
CELERY_DEFAULT_ROUTING_KEY = "task.default" 
CELERY_QUEUES = { 
    'default': { 
     'binding_key':'task.#', 
    }, 
    'i_tasks': { 
     'binding_key':'important_task.#', 
    }, 
} 

tasks.py

from celery.task import task 

@task(routing_key='important_task.update') 
def my_important_task(): 
    try: 
     ... 
    except Exception as exc: 
     my_important_task.retry(exc=exc) 

görev başlatın

settings.py: Burada

düzmece Sen bildirimleri yalnızca bellekte saklanır anlamına gelen bir simsar olarak Django ORM kullanan
+0

? Async_apply ile? – mher

+0

'apply_async() 'için kısayol olan' delay() 'yöntemini kullanıyorum. 'Routing_key' belirtimini, çağrıldığında yerine görev yöntemiyle (dekoratör aracılığıyla) tutmaya çalışıyorum. Ben bunun yerine apply_async() 'yi kullanarak anahtarı geçmeyi denedim ama aynı problemi alıyorum. –

+0

Gecikme, routing_key anahtar kelimesini kabul etmiyor. Apply_async'in basitleştirilmiş bir sürümüdür, ancak aynı değildir. – mher

cevap

43

Eğer routing_key ile bu görevi uyguladığınızda Yani

(http://readthedocs.org/docs/kombu/en/latest/introduction.html#transport-comparison de, nakil karşılaştırma tablosunu bulmak inarguably sert, bakınız) important_task.update, 'u yönlendiremez, çünkü henüz kuyruğu bildirmemiş.

Bunu eğer çalışacaktır:

@task(queue="i_tasks", routing_key="important_tasks.update") 
def important_task(): 
    print("IMPORTANT") 

Ama otomatik yönlendirme özelliğini kullanmak için çok daha kolay olurdu, 'Bir kullanmak gerekir gösterir burada bir şey yok çünkü

  • : konunun' değişimi, basitçe ayarları kaldırmak otomatik yönlendirme kullanmak Böyle 210,
  • CELERY_DEFAULT_EXCHANGE,
  • CELERY_DEFAULT_ROUTING_KEY
  • CELERY_QUEUES

  • CELERY_DEFAULT_EXCHANGE_TYPE
  • Ve beyan görev:

    @task(queue="important") 
    def important_task(): 
        return "IMPORTANT" 
    

    ve sonra bu kuyruktan tüketen bir işçiyi başlatmak için:

    $ python manage.py celeryd -l info -Q important 
    

    veya varsayılan (celery) kuyrukta ve important kuyrukta hem tüketmek:

    $ python manage.py celeryd -l info -Q celery,important 
    

    başka iyi uygulama görev içine kuyruk isimleri hardcode ve bunun yerine CELERY_ROUTES değil kullanmaktır :

    , daha sonra ayarlarınızda:

    CELERY_ROUTES = {"myapp.tasks.important_task": {"queue": "important"}} 
    

    Hala o zaman otomatik olarak tüm kuyruklar bir görev gönderildiğinde ilk kez ilan etmek bu yönlendirici ekleyebilirsiniz konu değişimleri kullanmakta ısrar edin: Eğer routing_key geçmesi nasıl

    class PredeclareRouter(object): 
        setup = False 
    
        def route_for_task(self, *args, **kwargs): 
         if self.setup: 
          return 
         self.setup = True 
         from celery import current_app, VERSION as celery_version 
         # will not connect anywhere when using the Django transport 
         # because declarations happen in memory. 
         with current_app.broker_connection() as conn: 
          queues = current_app.amqp.queues 
          channel = conn.default_channel 
          if celery_version >= (2, 6): 
           for queue in queues.itervalues(): 
            queue(channel).declare() 
          else: 
           from kombu.common import entry_to_queue 
           for name, opts in queues.iteritems(): 
            entry_to_queue(name, **opts)(channel).declare() 
    CELERY_ROUTES = (PredeclareRouter(),) 
    
    +0

    Açıklama için teşekkürler! –

    +2

    Bu sorun, Quelery 3'te sıraya alınan sıra bildirimleri ve değişimlerle mi ilgili? Ayarlarda yeni 'CELERY_QUEUES = (Kuyruk (...), ...)' kullanıyorum, bu kuyrukların düzgün bir şekilde bildirildiği anlamına mı geliyor? –

    +0

    Not: Celery 4.0'da CELERY_ROUTES, CELERY_TASK_ROUTES ile değiştirildi. Birinin zamanını kurtar. –

    İlgili konular