」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解 Celery 中的任務、代理人、工作人員和後端

了解 Celery 中的任務、代理人、工作人員和後端

發佈於2024-07-30
瀏覽:989

Understanding tasks, brokers, workers, and backends in Celery

芹菜学习起来可能令人望而生畏。虽然它的文档很全面,但它倾向于跳过基础知识。

这篇文章将定义 Celery 中的四个主要概念,讨论 Celery 和 Kombu 之间的关系,并使用一些代码示例来说明 Celery 在实际应用程序中如何有用。这些示例将使用 Django Web 框架及其 @shared_task 装饰器,但这些概念也适用于 Flask、FastAPI 等。

任务、代理、工作人员和后端

您将很难在当前的 Celery 文档中找到一个位置来清楚地说明它所认为的经纪人后端,但是通过足够的挖掘,您可以找到和推断定义。

以下是开始使用 Celery 之前您应该了解的概念。

任务

A 任务是Celery将异步执行的一些工作(在这种情况下,这是“不立即”的一个奇特词)。在 Web 应用程序中,一项任务可能是在用户提交表单后发送电子邮件。发送电子邮件可能是一个需要多秒的操作,并且强制用户在重定向之前等待电子邮件发送可能会让应用程序感觉很慢。

任务是使用 Celery 中的装饰器定义的。下面我们使用 @shared_task 装饰器将 send_thank_you_email() 转换为可在 Submit_feedback() 表单提交处理程序中使用的 Celery 任务。

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.",
        "[email protected]",
        [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})

当在 Celery 中使用装饰器定义任务时,它会向任务添加一个delay() 方法。您可以看到在成功保存表单后,send_thank_you_email 任务调用了上例中的delay() 方法。当delay()被调用时,它会将send_thank_you_email任务及其数据发送到存储它的broker,稍后将由worker执行,此时用户将通过电子邮件发送。

如果您在保存表单后需要发送额外的电子邮件,那么将工作推送到 Celery 的好处就变得更加明显。例如,您可能想向客户支持团队发送电子邮件,告知他们收到了新的反馈。对于 Celery,这几乎不会增加响应时间。

Celery 任务还允许额外的高级配置。如果电子邮件发送失败,您可以对任务进行编码以自动重试并配置 max_retries、retry_backoff、retry_jitter 等设置。

经纪人

Celery 增强提案的术语表对 消息代理有以下说法:

企业集成模式将消息代理定义为一个架构构建块,它可以从多个目的地接收消息,确定正确的目的地并将消息路由到正确的通道。

为了我们使用 Celery 的目的,我们将把 broker 视为存储创建的任务的“消息传输”。经纪人实际上并不执行任务:那是工人的工作。相反,代理是计划任务在计划任务时存储到,以及在工作人员最终执行任务时从拉出的地方。代理是 Celery 工作的必需的组件,Celery 将只连接到一个代理。

Celery 的后端和代理页面列出了一些其支持的代理,并且还有其支持但未列出的其他实验性代理(例如 SQLAlchemy)。这些代理(或“消息传输”)由 Celery 维护的 Python 消息传输库(称为 Kombu)管理。当寻找有关配置代理的信息时,查阅 Kombu 的文档而不是 Celery 的文档有时会很有帮助。

一些代理具有任务扇出和优先级等高级功能,而其他代理则作为简单队列运行。

工人

A worker 是 Celery 的一个实例,它从代理中提取任务并执行 Python 应用程序中定义的任务函数。 Celery 能够在其工作线程中运行 Python 代码,因为 Celery 本身是用 Python 编写的。

许多worker可以同时运行来执行任务。当您运行 celery worker 命令时,默认情况下它会为计算机的每个核心启动一个工作进程。如果你的电脑有16核,运行celeryworker将启动16个worker。

如果没有工作人员正在运行,消息(任务)将在代理中累积,直到工作人员可以执行它们。

后端

Celery 用户指南中的任务页面有以下关于 后端的内容

如果您想跟踪任务或需要返回值,那么 Celery 必须将状态存储或发送到某处,以便以后可以检索它们。有多种内置结果后端可供选择:SQLAlchemy/Django ORM、Memcached、RabbitMQ/QPid (rpc) 和 Redis – 或者您也可以定义自己的结果后端。

TLDR:后端跟踪异步任务的结果返回结果。这实际上意味着什么,什么时候有用?

假设您正在 Django 中构建一个可以生成年度报告的会计应用程序。该报告可能需要几分钟才能生成。

为了给您的用户提供响应更快的体验,您可以使用 AJAX 请求来启动报告生成任务。该请求返回任务的 ID,它可以使用该 ID 每隔几秒轮询一次服务器以查看是否生成了报告。任务完成后,它将返回报告的 ID,客户端可以使用该 ID 通过 JavaScript 显示报告的链接。

我们可以使用 Celery 和 Django 使用以下代码来实现这一点:

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})

在此示例中,generate_report_task()返回的资产ID存储在后端中。后端存储结果返回结果。后端存储尚未处理的任务的状态:只有在有结果后才会添加这些状态。返回“PENDING”的任务具有完全未知的状态:关联的任务甚至可能不存在。任务通常会返回“SUCCESS”或“FAILURE”,但您可以在 Celery 状态文档中查看所有状态。

Celery 运行任务不需要后端。 但是,如果您需要检查任务的结果或返回任务的结果,则需要后端。如果您在 Celery 未配置后端时尝试检查任务的状态,则会引发异常。


我希望这篇文章可以帮助您了解 Celery 的各个部分以及您可能考虑使用它的原因。虽然官方文档很难理解,但深入学习 Celery 可以在你的 Python 应用程序中释放新的可能性。

版本聲明 本文轉載於:https://dev.to/tylerlwsmith/defining-tasks-brokers-workers-and-backends-in-celery-1982?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在Java列表中有效計算元素的發生?
    如何在Java列表中有效計算元素的發生?
    計數列表中的元素出現在列表 中,在java編程中,列舉列表中列舉元素出現的任務來自列表。為此,收集框架提供了全面的工具套件。 在這種情況下,Batocurrences變量將保持值3,代表動物列表中的“ BAT”出現的數量。 &&& [此方法是簡單的,可以得出準確的結果,使其成為計算列表中元素出現的...
    程式設計 發佈於2025-02-06
  • 如何使用Delve在Visual Studio代碼中調試代碼?
    如何使用Delve在Visual Studio代碼中調試代碼?
    在Visual Studio代碼中調試GO代碼,並帶有delve 在Visual Studio for Go開發中設置Delve Debugger,需要以下步驟:[設置環境變量go15vendorexperiment = 1。 在.vscode文件夾中打開啟動.json文件。 通過單擊editor...
    程式設計 發佈於2025-02-06
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-02-06
  • 您應該選擇哪種MySQL數據類型:文本,斑點或clob?
    您應該選擇哪種MySQL數據類型:文本,斑點或clob?
    在mysql中的數據存儲選項:text vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs vs clob 文...
    程式設計 發佈於2025-02-06
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    在嘗試將image存儲在mysql數據庫中時,您可能會遇到一個可能會遇到問題。本指南將提供成功存儲您的圖像數據的解決方案。 easudy values('$ this-> ; image_id','file_get_contents($ tmp_imag...
    程式設計 發佈於2025-02-06
  • 為什麼我的GO數據庫/SQL查詢要比直接Postgres PSQL查詢要慢?
    為什麼我的GO數據庫/SQL查詢要比直接Postgres PSQL查詢要慢?
    使用數據庫/sql的查詢比直接查詢數據庫 QUERYing明顯慢,儘管使用了相同的查詢,但在執行A執行一個明顯的性能差異使用Postgres的PSQL實用程序直接查詢,並使用GO應用程序中的數據庫/SQL軟件包進行查詢。這種差異在PSQL中毫無疑問的查詢佔GO中的數十毫秒。數據庫/SQL初始化了一...
    程式設計 發佈於2025-02-06
  • 版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    在默認值中使用current_timestamp或mysql版本中的current_timestamp或在5.6.5 這種限制源於遺產實現的關注,這些限制需要為Current_timestamp功能提供特定的實現。消息和相關問題 `Productid` int(10)unsigned not ...
    程式設計 發佈於2025-02-06
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    如何為JavaScript對像變量創建動態鍵,嘗試為JavaScript對象創建動態鍵,使用此Syntax jsObj['key' i] = 'example' 1;將不起作用。正確的方法採用方括號:他們維持一個長度屬性,該屬性反映了數字屬性(索引)和一個數字屬性的數量。標準對像沒有模仿這...
    程式設計 發佈於2025-02-06
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣?使用openssl? 答案:可以使用mcrypt數據加密數據,可以使用openssl。關於如何使用openssl對McRypt進行加密的數據: openssl_decryp...
    程式設計 發佈於2025-02-06
  • 如何通過JavaScript中的鍵找到嵌套對象?
    如何通過JavaScript中的鍵找到嵌套對象?
    通過鍵 recursive solutive ); 如果(結果){ 休息; } } } 別的 { 對於(theObject中的var Prop){ con...
    程式設計 發佈於2025-02-06
  • 我如何使用Laravel \'s“ Orderby”關係訂購相關的模型記錄?
    我如何使用Laravel \'s“ Orderby”關係訂購相關的模型記錄?
    在Laravel中與Laravel的訂單關係一起檢索相關的模型記錄,從相關模型訪問數據時,可以對使用訂單方法的結果。例如,以下代碼檢索作者的所有註釋,並將它們顯示在列表中:但是,該列表不可用所需的序列排序。要根據帖子ID訂購結果,您可以擴展與查詢函數的關係:'列'參數指定要進行排序...
    程式設計 發佈於2025-02-06
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-02-06
  • PHP啟動錯誤:為什麼可以加載動態庫?
    PHP啟動錯誤:為什麼可以加載動態庫?
    [2遇到錯誤消息,表明未能加載動態庫。這些錯誤可能會顯著影響PHP功能,這對於迅速解決和解決這些錯誤至關重要。 此問題的一個常見原因是試圖加載未安裝的PHP擴展程序。要確定相關擴展名,請搜索PHP配置文件中包含擴展名=的行。利用GREP命令在PHP配置目錄中遞歸搜索:修改適當的配置文件,然後重新啟動...
    程式設計 發佈於2025-02-06
  • 潛入系統編程:C的初學者指南
    潛入系統編程:C的初學者指南
    探索系統編程:C 語言初學者指南系統編程涉及與計算機底層硬件和軟件交互。 C 語言是系統編程的首選語言之一,因為它能夠直接訪問硬件資源。這篇指南將帶你踏上系統編程之旅,從 C 語言基礎到實際應用案例。 C 語言基礎變量和數據類型:變量用於存儲數據。在C 中,變量必須聲明其數據類型,例如:int ag...
    程式設計 發佈於2025-02-06
  • 現代遊戲開發人員的高級JavaScript遊戲開發技術
    現代遊戲開發人員的高級JavaScript遊戲開發技術
    使用JavaScript構建遊戲比以往任何時候都更令人興奮。無論您是在編碼經典平台遊戲還是複雜的模擬,都知道如何充分利用工具,可以改變遊戲規則。本指南深入研究了JavaScript遊戲開發的基本策略和高級技術,這些技術可以幫助您提高自己的技巧。 1。遊戲開發中的網絡工作者 為什麼要使...
    程式設計 發佈於2025-02-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3