Wenn Sie Ihre Django-Anwendungen erstellen und skalieren, müssen Sie zwangsläufig bestimmte Aufgaben automatisch und regelmäßig im Hintergrund ausführen. Einige Beispiele: Regelmäßige Berichte erstellen Leeren Sie den Cache Massen-E-Mail-Benachrichtigungen senden Führen Sie eine nächtliche Wartung durch Dies ist eine der wenigen Funktionen, die zum Erstellen und Erweitern von Webanwendungen erforderlich sind und nicht Teil des Django-Kerns sind. Glücklicherweise bietet Celery mit Celery Beat eine leistungsstarke Lösung an, die sehr einfach zu implementieren ist. Im folgenden Artikel zeigen wir Ihnen, wie Sie Django, Celery und Redis mit Docker einrichten, um regelmäßig benutzerdefinierte Django-Admin-Befehle über Celery Beat auszuführen. Abhängigkeiten: Django v3.0.5 Docker v19.03.8 Python v3.8.2 Sellerie v4.4.1 Redis v5.0.8 Django + Celery-Reihe: Asynchrone Aufgaben mit Django und Celery Handhabung periodischer Aufgaben in Django mit Celery und Docker (Dieser Artikel!) Ziel Am Ende dieses Tutorials sollten Sie in der Lage sein: Containerisieren von Django, Celery und Redis mit Docker Integrieren Sie Celery in eine Django-Anwendung und erstellen Sie Aufgaben Schreiben benutzerdefinierter Django-Admin-Befehle Planen Sie benutzerdefinierte Django-Admin-Befehle zur regelmäßigen Ausführung über Celery Beat Projekt-Setup Klonen Sie das Basisprojekt aus
Da wir insgesamt vier Prozesse verwalten müssen (Django, Redis, Worker und Scheduler), verwenden wir Docker, um ihren Arbeitsablauf zu vereinfachen, indem wir sie miteinander verbinden, sodass sie alle mit einem einzigen Befehl aus einem einzigen Terminalfenster ausgeführt werden können. Erstellen Sie ein Image aus dem Stammverzeichnis des Projekts und starten Sie einen Docker-Container: $ docker-compose up -d --build $ docker-compose exec web python manage.py migrieren Navigieren Sie nach Abschluss des Builds zu http://localhost:1337, um sicherzustellen, dass die App wie erwartet ausgeführt wird. Sie sollten den folgenden Text sehen:
Projektstruktur:
Sellerie und Redis Jetzt müssen wir Container für Celery, Celery Beat und Redis hinzufügen. Fügen Sie zunächst die Abhängigkeiten zur Datei requirements.txt hinzu: Django==3.0.5 Sellerie == 4.4.1 redis==3.4.1 Inhalt der Datei Redis: Bild: redis:alpine Sellerie: Build: ./Projekt Befehl: celery -A core worker -l info Bände: - ./Projekt/:/usr/src/app/ Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - Redis Sellerie-Beat: Build: ./Projekt Befehl: Sellerie -A Core Beat -l Info Bände: - ./Projekt/:/usr/src/app/ Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - Redis Wir müssen auch den Abschnitt „depends_on“ des Webdienstes aktualisieren: Webseite: Build: ./Projekt Befehl: python manage.py runserver 0.0.0.0:8000 Bände: - ./Projekt/:/usr/src/app/ Häfen: 1337:8000 Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - redis # NEU Die vollständige Docker-Compose-Datei lautet wie folgt: Version: '3.7' Leistungen: Webseite: Build: ./Projekt Befehl: python manage.py runserver 0.0.0.0:8000 Bände: - ./Projekt/:/usr/src/app/ Häfen: 1337:8000 Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - Redis Redis: Bild: redis:alpine Sellerie: Build: ./Projekt Befehl: celery -A core worker -l info Bände: - ./Projekt/:/usr/src/app/ Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - Redis Sellerie-Beat: Build: ./Projekt Befehl: Sellerie -A Core Beat -l Info Bände: - ./Projekt/:/usr/src/app/ Umfeld: -DEBUG=1 - SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] hängt ab von: - Redis Bevor wir einen neuen Container erstellen, müssen wir Celery in unserer Django-Anwendung konfigurieren. Sellerie-Konfiguration aufstellen Erstellen Sie im Verzeichnis „core“ eine Datei celery.py und fügen Sie den folgenden Code hinzu: Betriebssystem importieren aus Sellerie importieren Sellerie os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") App = Sellerie("Kern") app.config_from_object("django.conf:Einstellungen", namespace="SELLERIE") app.autodiscover_tasks() Was ist hier los? Zuerst legen wir einen Standardwert für die Umgebungsvariable DJANGO_SETTINGS_MODULE fest, damit Celery weiß, wie es das Django-Projekt findet. Als Nächstes haben wir eine neue Celery-Instanz mit dem Namen „Core“ erstellt und diesen Wert einer Variablen namens „App“ zugewiesen. Anschließend haben wir die Celery-Konfigurationseinstellungen aus dem Einstellungsobjekt in django.conf geladen. Wir verwenden namespace="CELERY", um Konflikte mit anderen Django-Einstellungen zu vermeiden. Mit anderen Worten: Alle Konfigurationseinstellungen für Celery müssen mit dem Präfix CELERY_ versehen sein. Schließlich weist Fügen Sie den folgenden Code zu core/__init__.py hinzu: von .celery importiere App als celery_app __all__ = ("Sellerie-App",) Aktualisieren Sie abschließend die Datei core/settings.py mit den folgenden Celery-Einstellungen, damit eine Verbindung zu Redis hergestellt werden kann: CELERY_BROKER_URL = "redis://redis:6379" CELERY_RESULT_BACKEND = "redis://redis:6379" bauen: $ docker-compose up -d --build Zeigen Sie die Protokolle an: $ Docker-Compose-Protokolle „Web“ $ Docker-Compose-Protokolle „Sellerie“ $ Docker-Compose-Protokolle „Sellery-Beat“ $ Docker-Compose-Protokolle „Redis“ Wenn alles gut geht, haben wir jetzt vier Container, von denen jeder einen anderen Dienst erfüllt. Jetzt können wir eine Beispielaufgabe erstellen, um zu sehen, ob sie ordnungsgemäß funktioniert. Erstellen einer Aufgabe Erstellen Sie eine neue Datei core/tasks.py und fügen Sie den folgenden Code für eine Beispielaufgabe hinzu, die einfach auf der Konsole ausgibt: von Sellerie importiere shared_task @geteilte_Aufgabe def sample_task(): print("Die Beispielaufgabe wurde gerade ausgeführt.") Aufgaben planen Fügen Sie am Ende der Datei settings.py den folgenden Code hinzu, um die Ausführung von sample_task jede Minute mit Celery Beat zu planen: CELERY_BEAT_SCHEDULE = { "Beispielaufgabe": { "Aufgabe": "core.tasks.sample_task", "Zeitplan": crontab(Minute="*/1"), }, } Hier definieren wir eine periodische Aufgabe mit der Einstellung CELERY_BEAT_SCHEDULE. Wir haben die Aufgabe sample_task genannt und zwei Einstellungen deklariert: Task deklariert die auszuführende Aufgabe. Ein Zeitplan legt die Zeitintervalle fest, in denen eine Aufgabe ausgeführt werden soll. Dies kann eine Ganzzahl, ein Zeitdelta oder eine Crontab sein. Wir haben in unserer Aufgabe den Crontab-Modus verwendet und ihn angewiesen, jede Minute auszuführen. Weitere Informationen zum Zeitplan von Celery finden Sie hier. Stellen Sie sicher, dass Sie den Import hinzufügen: von celery.schedules importiere crontab core.tasks importieren Starten Sie den Container neu, um die Änderungen anzuwenden: $ docker-compose up -d --build Zeigen Sie die Protokolle an: $ docker-compose logs -f 'Sellerie' celery_1 | -------------- [Warteschlangen] celery_1 | .> celery Austausch=celery(direkt) Schlüssel=celery Sellerie_1 | Sellerie_1 | celery_1 | [Aufgaben] Sellerie_1 | . core.tasks.sample_task Wir können sehen, dass Celery die Beispielaufgabe core.tasks.sample_task erhalten hat. Jede Minute sollte im Protokoll eine Zeile mit der Endung „Die Beispielaufgabe wurde gerade ausgeführt“ angezeigt werden:
Anpassen von Django-Admin-Befehlen Django bietet viele integrierte Django-Admin-Befehle, wie zum Beispiel: wandern Starten Sie ein Projekt startapp Daten sichern Migrantin Zusätzlich zu den integrierten Befehlen bietet uns Django auch die Möglichkeit, unsere eigenen benutzerdefinierten Befehle zu erstellen: Benutzerdefinierte Verwaltungsbefehle sind besonders nützlich zum Ausführen eigenständiger Skripts oder Skripts, die regelmäßig über eine UNIX-Crontab oder die Systemsteuerung „Geplante Tasks“ von Windows ausgeführt werden. Daher konfigurieren wir zunächst einen neuen Befehl und führen ihn dann automatisch mit Celery Beat aus. Erstellen Sie zunächst eine neue Datei mit dem Namen orders/management/commands/my_custom_command.py. Fügen Sie dann den zum Ausführen erforderlichen Mindestcode hinzu: von django.core.management.base importiere BaseCommand, CommandError Klasse Command(BaseCommand): help = "Eine Beschreibung des Befehls" def-Handle (selbst, *Argumente, **Optionen): passieren BaseCommand hat einige Methoden, die überschrieben werden können, aber die einzige erforderliche Methode ist „handle“. Handle ist der Einstiegspunkt des benutzerdefinierten Befehls. Mit anderen Worten, wenn wir einen Befehl ausführen, wird diese Methode aufgerufen. Zu Testzwecken fügen wir normalerweise nur eine schnelle Druckanweisung hinzu. Gemäß der Django-Dokumentation wird jedoch empfohlen, stattdessen stdout.write zu verwenden: Wenn Sie Verwaltungsbefehle verwenden und Konsolenausgabe bereitstellen möchten, sollten Sie in self.stdout und self.stderr schreiben, anstatt direkt in stdout und stderr zu drucken. Durch die Verwendung dieser Proxys wird das Testen benutzerdefinierter Befehle wesentlich einfacher. Beachten Sie auch, dass Sie die Nachricht nicht mit einer neuen Zeile beenden müssen. Diese wird automatisch hinzugefügt, sofern Sie keinen Endparameter angeben. Fügen Sie also einen self.stdout.write-Befehl hinzu: von django.core.management.base importiere BaseCommand, CommandError Klasse Command(BaseCommand): help = "Eine Beschreibung des Befehls" def-Handle (selbst, *Argumente, **Optionen): self.stdout.write("Mein Beispielbefehl wurde gerade ausgeführt.") # NEU prüfen: $ docker-compose exec web python manage.py mein_benutzerdefinierter_Befehl Mein Beispielbefehl wurde gerade ausgeführt. Lassen Sie uns damit alles zusammenfassen! Planen benutzerdefinierter Befehle mit Celery Beat Nachdem unser Container nun läuft, wir getestet haben, ob wir die regelmäßige Ausführung von Aufgaben planen können, und unseren benutzerdefinierten Beispielbefehl für Django Admin geschrieben haben, ist es an der Zeit, ihn so einzurichten, dass unser benutzerdefinierter Befehl regelmäßig ausgeführt wird. aufstellen Im Projekt haben wir eine sehr einfache Anwendung namens Orders. Es enthält zwei Modelle: Produkt und Bestellung. Lassen Sie uns einen benutzerdefinierten Befehl erstellen, der einen E-Mail-Bericht mit der Bestätigung der Bestellungen des aktuellen Tages sendet. Zunächst fügen wir über die in diesem Projekt enthaltenen Vorrichtungen einige Produkte und Bestellungen zur Datenbank hinzu: $ docker-compose exec web python manage.py loaddata products.json Erstellen Sie einen Superuser: $ docker-compose exec web python manage.py createsuperuser Geben Sie bei der entsprechenden Aufforderung Ihren Benutzernamen, Ihre E-Mail-Adresse und Ihr Passwort ein. Navigieren Sie dann in Ihrem Webbrowser zu http://127.0.0.1:1337/admin. Melden Sie sich mit dem soeben erstellten Superuser an und erstellen Sie einige Bestellungen. Stellen Sie sicher, dass mindestens ein Datum heute ist. Erstellen wir einen neuen benutzerdefinierten Befehl für unseren E-Mail-Bericht. Erstellen Sie eine Datei mit dem Namen orders/management/commands/email_report.py: von Datum/Uhrzeit importiere Zeitdelta, Zeit, Datum/Uhrzeit von django.core.mail importiere mail_admins von django.core.management importiere BaseCommand von django.utils importiere Zeitzone von django.utils.timezone importiere make_aware aus orders.models importiere Order heute = Zeitzone.jetzt() morgen = heute + Zeitdelta(1) today_start = make_aware(datetime.combine(heute, zeit())) today_end = make_aware(datetime.combine(morgen, zeit())) Klasse Command(BaseCommand): help = "Bericht zu heutigen Bestellungen an Administratoren senden" def-Handle (selbst, *Argumente, **Optionen): Bestellungen = Bestellung.Objekte.Filter(bestätigter_Datumsbereich=(heute_Beginn, heute_Ende)) bei Bestellungen: Nachricht = "" zur Bestellung in Bestellungen: Nachricht += f"{Bestellung} \n" Betreff = ( f"Bestellbericht für {today_start.strftime('%Y-%m-%d')}" f"bis {heute_end.strftime('%Y-%m-%d')}" ) mail_admins(Betreff=Betreff, Nachricht=Nachricht, HTML-Nachricht=Keine) self.stdout.write("E-Mail-Bericht wurde gesendet.") anders: self.stdout.write("Heute wurden keine Bestellungen bestätigt.") Im Code haben wir die Datenbank nach Bestellungen mit dem Datum „confirmed_date“ abgefragt, die Bestellungen zu einer einzigen Nachricht für den E-Mail-Text zusammengefasst und die E-Mail dann mit dem in Django integrierten Befehl „mail_admins“ an die Administratoren gesendet. Fügen Sie eine Dummy-Administrator-E-Mail hinzu und legen Sie EMAIL_BACKEND fest, um das Konsolen-Backend zu verwenden, sodass die E-Mail in der Einstellungsdatei an stdout gesendet wird: EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" DEFAULT_FROM_EMAIL = "[email protected]" ADMINS = [("Testbenutzer", "[email protected]"), ] laufen:
Sellerie-Beat Jetzt müssen wir eine periodische Aufgabe erstellen, um diesen Befehl jeden Tag auszuführen. Fügen Sie core/tasks.py eine neue Aufgabe hinzu: von Sellerie importiere shared_task von django.core.management importiere call_command # NEU @geteilte_Aufgabe def sample_task(): print("Die Beispielaufgabe wurde gerade ausgeführt.") #NEU @geteilte_Aufgabe auf Grund von send_email_report(): Anrufbefehl("E-Mail-Bericht", ) Also haben wir zuerst einen call_command-Import hinzugefügt, der verwendet wird, um Django-Admin-Befehle programmgesteuert aufzurufen. Verwenden Sie in der neuen Aufgabe dann call_command als Argument mit dem Namen Ihres benutzerdefinierten Befehls. Um diese Aufgabe zu planen, öffnen Sie die Datei core/settings.py und aktualisieren Sie die Einstellung CELERY_BEAT_SCHEDULE, um die neue Aufgabe einzuschließen. CELERY_BEAT_SCHEDULE = { "Beispielaufgabe": { "Aufgabe": "core.tasks.sample_task", "Zeitplan": crontab(Minute="*/1"), }, "E-Mail-Bericht senden": { "Aufgabe": "core.tasks.send_email_report", "Zeitplan": crontab(Stunde="*/1"), }, } Hier haben wir CELERY_BEAT_SCHEDULE einen neuen Eintrag namens send_email_report hinzugefügt. Wie bei der vorherigen Aufgabe deklarieren wir die Aufgabe, die diese Aufgabe ausführen soll – zum Beispiel core.tasks.send_email_report – und legen die Wiederholung im Crontab-Modus fest. Starten Sie den Container neu, um sicherzustellen, dass die neuen Einstellungen aktiv sind: $ docker-compose up -d --build Schauen Sie sich das Protokoll an: $ docker-compose logs -f 'Sellerie' celery_1 | -------------- [Warteschlangen] celery_1 | .> celery Austausch=celery(direkt) Schlüssel=celery Sellerie_1 | Sellerie_1 | celery_1 | [Aufgaben] Sellerie_1 | . core.tasks.sample_task Sellerie_1 | . core.tasks.send_email_report Eine Minute später wurde die E-Mail versendet:
abschließend In diesem Artikel haben wir Sie durch die Einrichtung von Docker-Containern für Celery, Celery Beat und Redis geführt. Anschließend haben wir gezeigt, wie man mit Celery Beat einen benutzerdefinierten Django-Admin-Befehl und eine regelmäßige Aufgabe erstellt, um diesen Befehl automatisch auszuführen. Originalartikel: https://testdriven.io/blog/django-celery-periodic-tasks/ Dies ist das Ende dieses Artikels zur Verwendung von Celery und Docker zur Handhabung periodischer Aufgaben in Django. Weitere Informationen zur Handhabung periodischer Aufgaben in Django durch Celery Docker finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Analyse des Prinzips und der Verwendung der kontinuierlichen MySQL-Aggregation
>>: Vite führt die Implementierung virtueller Dateien ein
1 Behalten Sie das RPM-Paket bei, das heruntergel...
Docker wird immer ausgereifter und seine Funktion...
Seitendomänenbeziehung: Die Hauptseite a.html gehö...
Auf einem Server werden drei MySQL-Instanzprozess...
Der Blogger hat MySQL ein oder zwei Monate lang n...
Als grundlegendes Element einer Webseite sind Bil...
Erstens: Installation von MySQL Laden Sie die MyS...
Wenn Sie den Docker-Container nach dem Betreten d...
Inhaltsverzeichnis Cache Klassifizierung des Cach...
1. Einleitung Im Projekt wird MySQL verwendet. Ic...
Dieser Artikel zeichnet das Installations- und Ko...
In diesem Artikelbeispiel wird der spezifische Co...
MySQL wird in eine Installationsversion und eine ...
brauchen: Verwenden Sie Vue, um das Scannen von Q...
Sogenanntes Talent (linke und rechte Gehirnhälfte...