Heim  >  Artikel  >  Backend-Entwicklung  >  Aufgaben, Broker, Worker und Backends in Celery verstehen

Aufgaben, Broker, Worker und Backends in Celery verstehen

PHPz
PHPzOriginal
2024-07-23 20:37:53382Durchsuche

Understanding tasks, brokers, workers, and backends in Celery

Sellerie kann entmutigend zu lernen sein. Obwohl die Dokumentation umfassend ist, neigt sie dazu, die Grundlagen zu überspringen.

In diesem Beitrag werden vier der Hauptkonzepte in Celery definiert, die Beziehung zwischen Celery und Kombu erörtert und anhand einiger Codebeispiele veranschaulicht, wie Celery in realen Anwendungen nützlich sein könnte. In den Beispielen werden das Django-Webframework und sein @shared_task-Dekorator verwendet, aber die Konzepte sind auch auf Flask, FastAPI und andere anwendbar.

Aufgaben, Broker, Worker und Backends

Es wird Ihnen schwer fallen, in der aktuellen Celery-Dokumentation eine Stelle zu finden, die klar darlegt, was ein Broker oder Backend ist, aber mit genügend Recherche können Sie finden und Definitionen ableiten.

Im Folgenden finden Sie Konzepte, die Sie kennen sollten, bevor Sie mit Sellerie beginnen.

Aufgabe

Eine Aufgabe ist eine Arbeit, die Celery asynchron ausführt (in diesem Zusammenhang ist das ein schickes Wort für „nicht sofort“). In einer Webanwendung könnte eine Aufgabe darin bestehen, eine E-Mail zu senden, nachdem ein Benutzer ein Formular übermittelt hat. Das Senden einer E-Mail kann ein Vorgang von mehreren Sekunden sein, und wenn ein Benutzer gezwungen wird, auf das Senden einer E-Mail zu warten, bevor er umgeleitet wird, kann dies dazu führen, dass sich eine Anwendung langsam anfühlt.

Aufgaben werden mithilfe von Dekoratoren in Celery definiert. Im Folgenden verwenden wir den @shared_task-Dekorator, um send_thank_you_email() in eine Celery-Aufgabe umzuwandeln, die im Submit_feedback()-Formularübermittlungshandler verwendet werden kann.

from config.celery import shared_task
from django.core.mail import send_mail
from django.shortcuts import render, redirect
from feedback.forms import FeedbackForm

@shared_task
def send_thank_you_email(email_address):
    send_mail(
        "Thank you for your feedback!",
        "We appreciate your input.",
        "noreply@example.com",
        [email_address],
    )

def submit_feedback(request):
    if request.method == "POST":
        form = FeedbackForm(request.POST)
        if form.is_valid():
            form.save()

            # Push the task to the broker using the delay() method.
            send_thank_you_email.delay(form.cleaned_data["email"])

            return redirect("/thank-you/")
    else:
        form = FeedbackForm()

    return render(request, "feedback.html", {"form": form})

Wenn eine Aufgabe mithilfe eines Dekorators in Celery definiert wird, wird der Aufgabe eine Methode „delay()“ hinzugefügt. Im obigen Beispiel können Sie sehen, wie die Aufgabe send_thank_you_email die Methode „delay()“ aufruft, nachdem das Formular erfolgreich gespeichert wurde. Wenn „delay()“ aufgerufen wird, sendet es die Aufgabe „send_thank_you_email“ und ihre Daten an den Broker, wo sie gespeichert wird und später von einem Worker ausgeführt wird, woraufhin der Benutzer dies tut per E-Mail gesendet werden.

Der Vorteil der Verlagerung der Arbeit auf Celery wird deutlicher, wenn Sie nach dem Speichern des Formulars weitere E-Mails senden müssen. Beispielsweise möchten Sie dem Kundensupport-Team möglicherweise per E-Mail mitteilen, dass es neues Feedback erhalten hat. Bei Sellerie bedeutet dies fast keine zusätzliche Reaktionszeit.

Sellerie-Aufgaben ermöglichen auch eine zusätzliche erweiterte Konfiguration. Für den Fall, dass eine E-Mail nicht gesendet werden konnte, können Sie Ihre Aufgabe so programmieren, dass sie automatisch erneut versucht, und Einstellungen wie max_retries, retry_backoff, retry_jitter usw. konfigurieren.

Makler

Das Glossar der Celery Enhancement Proposals sagt Folgendes über Message Brokers:

Enterprise Integration Patterns definiert einen Message Broker als einen Architekturbaustein, der Nachrichten von mehreren Zielen empfangen, das richtige Ziel bestimmen und die Nachricht an den richtigen Kanal weiterleiten kann.

Für unsere Zwecke mit Celery betrachten wir einen Broker als „Nachrichtentransport“, in dem erstellte Aufgaben gespeichert werden. Makler führen die Aufgabe nicht wirklich aus: Das ist die Aufgabe eines Arbeiters. Stattdessen sind Broker der Ort, an dem geplante Aufgaben gespeichert werden, wenn eine Aufgabe geplant wird, und von diesem Ort abgerufen werden, wenn ein Mitarbeiter schließlich eine Aufgabe ausführt. Ein Broker ist eine erforderliche Komponente, damit Celery funktioniert, und Celery stellt eine Verbindung zu genau einem Broker her.

Die Seite „Backends und Broker“ von Celery listet einige der unterstützten Broker auf, und es gibt andere unterstützte experimentelle Broker, die nicht aufgeführt sind (z. B. SQLAlchemy). Diese Broker (oder „Nachrichtentransporte“) werden von einer von Celery gepflegten Python-Bibliothek für Nachrichtentransporte namens Kombu verwaltet. Wenn Sie nach Informationen zum Konfigurieren von Brokern suchen, ist es manchmal hilfreich, die Dokumentation von Kombu anstelle der von Celery zu konsultieren.

Einige Broker verfügen über erweiterte Funktionen wie Aufgaben-Fanout und -Priorität, während andere als einfache Warteschlangen arbeiten.

Arbeitnehmer

Ein Worker ist eine Instanz von Celery, die Aufgaben vom Broker abruft und die in Ihrer Python-App definierten Aufgabenfunktionen ausführt. Celery kann Python-Code in seinen Workern ausführen, da Celery selbst in Python geschrieben ist.

Viele Arbeiter können gleichzeitig laufen, um Aufgaben auszuführen. Wenn Sie den Befehl celery worker ausführen, wird standardmäßig ein Worker für jeden Kern Ihres Computers gestartet. Wenn Ihr Computer über 16 Kerne verfügt, werden durch die Ausführung von Celery Worker 16 Worker gestartet.

Wenn keine Worker ausgeführt werden, sammeln sich Nachrichten (Aufgaben) im Broker an, bis Worker zur Ausführung verfügbar sind.

Backend

Auf der Aufgabenseite im Celery-Benutzerhandbuch steht Folgendes zu Backends:

If you want to keep track of tasks or need the return values, then Celery must store or send the states somewhere so that they can be retrieved later. There are several built-in result backends to choose from: SQLAlchemy/Django ORM, Memcached, RabbitMQ/QPid (rpc), and Redis – or you can define your own.

TLDR: a backend tracks the outcomes and returned results of async tasks. What does that actually mean, and when could it be useful?

Imagine you are building an accounting app in Django that can generate an annual report. The report could take minutes to generate.

To give your users a more responsive experience, you use an AJAX request to kick off a report generation task. That request returns an ID of the task, which it can use to poll the server every few seconds to see if the report is generated. Once the task is complete, it will return the ID of the report, which the client can use to display a link to the report via JavaScript.

We can implement this with Celery and Django using the following code:

from celery import shared_task
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from accounting.models import Asset
from accounting.reports import AnnualReportGenerator

@shared_task
def generate_report_task(year):
    # This could take minutes...
    report = AnnualReportGenerator().generate(year)
    asset = Asset.objects.create(
        name=f"{year} annual report",
        url=report.url,
    )
    return asset.id

@require_http_methods(["POST"])
def generate_annual_report_view(request):
    year = request.POST.get("year")
    task = generate_report_task.delay(year)
    return JsonResponse({"taskId": task.id})

def get_annual_report_generation_status_view(request, task_id):
    task = generate_report_task.AsyncResult(task_id)

    # The status is typically "PENDING", "SUCCESS", or "FAILURE"
    status = task.status
    return JsonResponse({"status": status, "assetId": task.result})

In this example, the asset ID returned by generate_report_task() is stored in a backend. The backend stores the outcome and returned result. The backend does not store the status of yet-to-be-processed tasks: these will only be added once there has been an outcome. A task that returns "PENDING" has a completely unknown status: an associated task might not even exist. Tasks will typically return "SUCCESS" or "FAILURE", but you can see all statuses in the Celery status docs.

Having a backend is not required for Celery to run tasks. However, it is required if you ever need to check the outcome of a task or return a task's result. If you try to check a task's status when Celery does not have a backend configured, an exception will be raised.


I hope this post helps you understand the individual pieces of Celery and why you might consider using it. While the official documentation is challenging to grok, learning Celery deeply can unlock new possibilities within your Python applications.

Das obige ist der detaillierte Inhalt vonAufgaben, Broker, Worker und Backends in Celery verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn