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

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

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

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]刪除
最新教學 更多>
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-12-19
  • 儘管程式碼有效,為什麼 POST 請求無法擷取 PHP 中的輸入?
    儘管程式碼有效,為什麼 POST 請求無法擷取 PHP 中的輸入?
    解決PHP 中的POST 請求故障在提供的程式碼片段:action=''而非:action="<?php echo $_SERVER['PHP_SELF'];?>";?>"檢查$_POST陣列:表單提交後使用 var_dump 檢查 $_POST 陣列的內容...
    程式設計 發佈於2024-12-19
  • 插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
    插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
    插入記錄時如何解決「一般錯誤:2006 MySQL 伺服器已消失」介紹:將資料插入MySQL 資料庫有時會導致錯誤「一般錯誤:2006 MySQL 伺服器已消失」。當與伺服器的連線遺失時會出現此錯誤,通常是由於 MySQL 配置中的兩個變數之一所致。 解決方案:解決此錯誤的關鍵是調整wait_tim...
    程式設計 發佈於2024-12-19
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-12-19
  • Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    程式設計 發佈於2024-12-19
  • 如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    在 PHP 中組合關聯數組在 PHP 中,將兩個關聯數組組合成一個數組是常見任務。考慮以下請求:問題描述:提供的代碼定義了兩個關聯數組,$array1和$array2。目標是建立一個新陣列 $array3,它合併兩個陣列中的所有鍵值對。 此外,提供的陣列具有唯一的 ID,而名稱可能重疊。要求是建構一...
    程式設計 發佈於2024-12-19
  • TB 級資料庫的 MySQL 與 NoSQL:聚集索引何時是正確的解決方案?
    TB 級資料庫的 MySQL 與 NoSQL:聚集索引何時是正確的解決方案?
    MySQL:探索資料庫設計迷宮優化大型資料庫時,必須考慮資料庫設計策略以提高效能。在給定的場景中,包含執行緒的 TB 級資料庫由於其龐大的規模而面臨效能挑戰。本文探討了 MySQL 和 NoSQL 之間的選擇,重點介紹了 MySQL 的 innodb 引擎及其聚集索引的優點。 了解 MySQL 的 ...
    程式設計 發佈於2024-12-19
  • 為什麼我的 Spring Boot 應用程式不自動建立資料庫架構?
    為什麼我的 Spring Boot 應用程式不自動建立資料庫架構?
    在 Spring Boot 中自動建立資料庫架構啟動 Spring Boot 應用程式時,可能會遇到自動建立資料庫架構的問題。以下故障排除步驟旨在解決此問題:1.實體類別包:確保實體類別位於使用@EnableAutoConfiguration註解的類別的同一個套件或子包中。否則,Spring 將不會...
    程式設計 發佈於2024-12-18
  • CSS3 轉場是否提供事件來偵測起點和終點?
    CSS3 轉場是否提供事件來偵測起點和終點?
    了解 CSS3 過渡事件CSS3 過渡允許在 Web 元素上實現流暢的動畫和視覺效果。為了增強使用者體驗並使操作與這些轉換同步,監控其進度非常重要。本文解決了 CSS3 是否提供事件來檢查過渡何時開始或結束的問題。 W3C CSS 過渡草案W3C CSS 過渡草案規定CSS 轉換會觸發對應的 DOM...
    程式設計 發佈於2024-12-18
  • Java 中可以手動釋放記憶體嗎?
    Java 中可以手動釋放記憶體嗎?
    Java 中的手動內存釋放與垃圾回收與C 不同,Java 採用託管內存框架來處理內存分配和釋放由垃圾收集器(GC) 自動執行。這種自動化方法可以提高記憶體利用率並防止困擾 C 程式的記憶體洩漏。 Java 中可以手動釋放記憶體嗎? 由於 Java 的記憶體管理是由GC,它沒有提供像 C 中的 fre...
    程式設計 發佈於2024-12-18
  • Java 1.6 中如何可靠地確定檔案是否為符號連結?
    Java 1.6 中如何可靠地確定檔案是否為符號連結?
    在 Java 1.6 中驗證符號連結確定符號連結的存在對於各種文件處理操作至關重要。在 Java 中,識別符號連結時需要考慮一些潛在問題,特別是在目錄遍歷的上下文中。 檢查符號連結的常見方法是比較文件的絕對路徑和規範路徑。規範路徑表示檔案的標準化路徑,而絕對路徑可能包括符號連結。傳統上,概念是如果這...
    程式設計 發佈於2024-12-17
  • 如何使背景顏色透明,同時保持文字不透明?
    如何使背景顏色透明,同時保持文字不透明?
    背景顏色的不透明度而不影響文本在Web 開發領域,實現透明度通常對於增強視覺吸引力和網站元素的功能。常見的要求是對 div 背景套用透明度,同時保留所包含文字的不透明度。這可能會帶來挑戰,特別是在確保跨瀏覽器相容性方面。 rgba 解決方案最有效且廣泛支持的解決方案是利用「RGBA」(紅、綠、藍、A...
    程式設計 發佈於2024-12-17
  • PHP 字串比較:`==`、`===` 或 `strcmp()` – 您應該使用哪個運算子?
    PHP 字串比較:`==`、`===` 或 `strcmp()` – 您應該使用哪個運算子?
    PHP 中的字串比較:'=='、'===' 或 'strcmp()'? PHP 中的字串比較PHP 可以使用不同的運算子來完成,例如「==」、「===」或「strcmp()」函數。此比較涉及檢查兩個字串是否相等。 '==' 與'...
    程式設計 發佈於2024-12-17
  • 如何自訂操作列的按鈕和外觀?
    如何自訂操作列的按鈕和外觀?
    自訂操作欄的按鈕和外觀要實現所需的自訂操作欄外觀,請考慮以下步驟: 1.建立自訂操作按鈕若要將圖片包含為按鈕,請透過擴充Button類別來定義自訂視圖。然後可以將此自訂視圖顯示在 ActionBar 上,如下所示:<Button android:id="@ id/my_cus...
    程式設計 發佈於2024-12-17
  • 介紹 Laravel 的履歷解析器/CV 解析器
    介紹 Laravel 的履歷解析器/CV 解析器
    照片由 Mohammad Rahmani 在 Unsplash 上拍攝 基於我們的 Resume/CV Parsing AI API 端點的流行,我們專門為您製作了一個專門的輕量級 Laravel 庫。 招募的未來:敏銳、精確且對 Laravel 友好 這個新套件可在 github...
    程式設計 發佈於2024-12-17

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

Copyright© 2022 湘ICP备2022001581号-3