celery - eine asynchrone task queue (nicht nur) für django
DESCRIPTION
Celery ist ein asynchroner Task Queue, der als Middleware große Mengen von Nachrichten verarbeiten kann. Da Celery in Python geschrieben ist eignet es sich gut, um als Task Queue für Django Applikationen eingesetzt zu werden. Als Backends stehen RabbitMQ, Redis und der Ghetto Queue (RDBMS & Cron) zur Verfügung. Mit Celery lassen sich große Mengen von Nachrichten synchron und asynchron verarbeiten. Nur auf einer Maschine als auch in einem Szenario mit mehreren Servern.TRANSCRIPT
![Page 1: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/1.jpg)
CeleryEine asynchrone Task Queue
(nicht nur) für DjangoMarkus Zapke-Gründemann
FrOSCon 2010
![Page 2: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/2.jpg)
MarkusZapke-Gründemann• Softwareentwickler seit 2001
• Schwerpunkt: Web Application Development mit Python und PHP
• Django, symfony & Zend Framework
• Freier Softwareentwickler und Berater seit 2008
• www.keimlink.de
![Page 3: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/3.jpg)
Überblick
• Warum eine Task Queue?
• Celery
• Python Task
• Django Task
• Zeitgesteuerter Task
• Webhook
![Page 4: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/4.jpg)
Warum eineTask Queue?
• Entkoppeln von Informationsproduzenten und -konsumenten
• Asynchrone Verarbeitung
• Skalierbarkeit
![Page 5: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/5.jpg)
ProduzentTask
Queue Konsument
![Page 6: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/6.jpg)
ProduzentTask
Queue Konsument
Produzent
Produzent
Konsument
Konsument
![Page 7: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/7.jpg)
ProduzentTask
Queue Konsument
Produzent
Produzent
Konsument
Konsument
![Page 8: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/8.jpg)
ProduzentTask
Queue Konsument
Produzent
Produzent
Konsument
Konsument
![Page 9: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/9.jpg)
Celery
• Autor: Ask Solem
• RabbitMQ, Stomp, Redis und Ghetto Queue
• Clustering mit RabbitMQ
• Parallele Ausführung
• Zeitgesteuerte Ausführung
![Page 10: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/10.jpg)
Celery
• Rückgabewert sofort oder später verarbeiten
• Speichern der Rückgabe in „Result Stores“
• Webhooks
• Serialisierung (Pickle, JSON, YAML)
• Wiederholen abgebrochener Tasks
![Page 11: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/11.jpg)
Celery
• Callbacks
• Task Sets
• Logging
• Bei Fehler E-Mail versenden
• Ausführliche Dokumentation
• BSD Lizenz
![Page 12: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/12.jpg)
Celery Komponenten
• celeryd
• celerybeat
• celerymon
• SQLAlchemy
• carrot
• anyjson
![Page 13: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/13.jpg)
Celery Installation
$ pip install celery
$ easy_install celery
![Page 14: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/14.jpg)
Python Task# Task als Klassefrom celery.task import Taskfrom myproject.models import User
class CreateUserTask(Task): def run(self, username, password): User.create(username, password)
>>> from tasks import CreateUserTask>>> CreateUserTask().delay('john', 'secret')
# Task als Funktion mit Decoratorfrom celery.decorators import taskfrom myproject.models import User
@taskdef create_user(username, password): User.create(username, password)
>>> from tasks import create_user>>> create_user.delay('john', 'secret')
![Page 15: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/15.jpg)
Python Task@task() # Benutzt pickle, um das Objekt zu serialisieren.def check_means(user): return user.has_means()
>>> from tasks import check_means>>> result = check_means.delay(user)>>> result.ready() # Gibt True zurück wenn der Task beendet ist.False>>> result.result # Task ist noch nicht beendet, kein Ergebnis verfügbar.None>>> result.get() # Warten bis der Task fertig ist und Ergebnis zurückgeben.93.27>>> result.result # Jetzt ist ein Ergebnis da.93.27>>> result.successful() # War der Task erfolgreich?True
![Page 16: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/16.jpg)
Python TaskKonfiguration
$ celeryd --loglevel=INFO
# celeryconfig.pyBROKER_HOST = "localhost"BROKER_PORT = 5672BROKER_USER = "myuser"BROKER_PASSWORD = "mypassword"BROKER_VHOST = "myvhost"
CELERY_RESULT_BACKEND = "database"CELERY_RESULT_DBURI = "mysql://user:password@host/dbname"
CELERY_IMPORTS = ("tasks", )
![Page 17: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/17.jpg)
Zeitgesteuerter Task# Periodic taskfrom celery.decorators import periodic_taskfrom datetime import timedelta
@periodic_task(run_every=timedelta(seconds=30))def every_30_seconds(): print("Running periodic task!")
# crontabfrom celery.task.schedules import crontabfrom celery.decorators import periodic_task
@periodic_task(run_every=crontab(hour=7, minute=30, day_of_week=1))def every_monday_morning(): print("Execute every Monday at 7:30AM.")
$ celerybeat$ celeryd -B
![Page 18: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/18.jpg)
Django TaskInstallation
$ pip install django-celery
$ easy_install django-celery
![Page 19: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/19.jpg)
Django TaskSpamfilter
![Page 20: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/20.jpg)
Produzent
blog.views.add_comment
Django TaskSpamfilter
![Page 21: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/21.jpg)
Produzent
blog.views.add_comment
CommentModel
Django TaskSpamfilter
![Page 22: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/22.jpg)
Produzent
blog.views.add_comment
CommentModel
comment.save()
Django TaskSpamfilter
![Page 23: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/23.jpg)
Task QueueProduzent
blog.views.add_comment
CommentModel
comment.save()
Django TaskSpamfilter
![Page 24: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/24.jpg)
Task QueueProduzent
blog.views.add_comment
CommentModel
comment.save()
blog.tasks.spam_filter.delay(comment.id, remote_addr)
Django TaskSpamfilter
![Page 25: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/25.jpg)
Task QueueProduzent
blog.views.add_comment
Konsument
blog.tasks.spam_filter
CommentModel
comment.save()
blog.tasks.spam_filter.delay(comment.id, remote_addr)
Django TaskSpamfilter
![Page 26: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/26.jpg)
Task QueueProduzent
blog.views.add_comment
Konsument
blog.tasks.spam_filter
CommentModel
comment.save()
blog.tasks.spam_filter.delay(comment.id, remote_addr)
Django TaskSpamfilter
![Page 27: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/27.jpg)
Task QueueProduzent
blog.views.add_comment
Konsument
blog.tasks.spam_filter
CommentModel
comment.save()
blog.tasks.spam_filter.delay(comment.id, remote_addr)
comment.is_spam = Truecomment.save()
Django TaskSpamfilter
![Page 28: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/28.jpg)
blog/tasks.py@taskdef spam_filter(comment_id, remote_addr=None, **kwargs): logger = spam_filter.get_logger(**kwargs) logger.info("Running spam filter for comment %s" % comment_id)
comment = Comment.objects.get(pk=comment_id) current_domain = Site.objects.get_current().domain akismet = Akismet(settings.AKISMET_KEY, "http://%s" % domain) if not akismet.verify_key(): raise ImproperlyConfigured("Invalid AKISMET_KEY")
is_spam = akismet.comment_check(user_ip=remote_addr, comment_content=comment.comment, comment_author=comment.name, comment_author_email=comment.email_address) if is_spam: comment.is_spam = True comment.save()
return is_spam
![Page 29: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/29.jpg)
Django TaskKonfiguration
# settings.pyINSTALLED_APPS += ("djcelery", )import djcelerydjcelery.setup_loader()
BROKER_HOST = "localhost"BROKER_PORT = 5672BROKER_USER = "myuser"BROKER_PASSWORD = "mypassword"BROKER_VHOST = "myvhost"
$ python manage.py syncdb$ python manage.py celeryd -l info
![Page 30: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/30.jpg)
Webhook
# POST>>> from celery.task.http import URL>>> res = URL("http://example.com/multiply").get_async(x=10, y=10)>>> res.get() # {"status": "success", "retval": 100}100
# GET>>> from celery.task.http import HttpDispatchTask>>> url = "http://example.com/multiply">>> res = HttpDispatchTask.delay(url, method="GET", x=10, y=10)>>> res.get() # {"status": "success", "retval": 100}100
![Page 31: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/31.jpg)
Links
• http://celeryproject.org/
• http://github.com/ask/celery
• http://pypi.python.org/pypi/celery
• http://pypi.python.org/pypi/django-celery
• http://pypi.python.org/pypi/celerymon
![Page 32: Celery - eine asynchrone Task Queue (nicht nur) für Django](https://reader033.vdocuments.mx/reader033/viewer/2022052619/555a4f2dd8b42a47748b4883/html5/thumbnails/32.jpg)
LizenzDieses Werk ist unter einem Creative Commons
Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenzvertrag
lizenziert.
Um die Lizenz anzusehen, gehen Sie bitte zu http://creativecommons.org/licenses/by-sa/3.0/
oder schicken Sie einen Brief an Creative Commons, 171 Second Street, Suite 300, San
Francisco, California 94105, USA.