”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Celery 和 Docker 在 Django 中运行 Cron 作业

使用 Celery 和 Docker 在 Django 中运行 Cron 作业

发布于2024-09-01
浏览:350

Running a Cron Job in Django Using Celery and Docker

Cron 作业简介

cron 作业是按指定时间间隔自动运行的计划任务。这些任务对于自动执行重复操作(例如发送提醒电子邮件、生成报告或清理数据库)非常有用。在 Django 项目中,可以使用 Celery 等工具设置 cron 作业,这使得调度和管理任务变得简单高效。

设置您的 Django 项目

我们首先创建一个 Django 项目,安装必要的包,然后使用 Docker 容器化该项目。

创建虚拟环境并安装Django和DRF

  • 打开终端并导航到项目目录。
  • 创建并激活虚拟环境:
python -m venv myenv
source myenv/bin/activate  # On Windows, use myenv\Scripts\activate
  • 安装 Django 和 Django REST Framework:
pip install django djangorestframework

创建 Django 项目和应用程序

  • 创建一个新的 Django 项目:
django-admin startproject myproject
cd myproject
  • 创建一个新的 Django 应用程序:
python manage.py startapp myapp
  • 将应用程序添加到您的settings.py:
# myproject/settings.py

INSTALLED_APPS = [
    ...
    'myapp',
    'rest_framework',
]

安装 Celery 和 Redis

  • 安装 Celery 和 Redis:
pip install celery redis
  • 通过创建 celery.py 文件在您的项目中设置 Celery:
# myproject/celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

app.conf.beat_schedule = {
    'run-this-task-every-day': {
        'task': 'myapp.tasks.my_scheduled_task',
        'schedule': crontab(minute="00", hour="7"),  # Executes every day at 7 AM
    },
}

app.conf.timezone = 'UTC'
  • 修改init.py以使用Django加载Celery:
# myproject/__init__.py
from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app

__all__ = ('celery_app',)
  • 在settings.py中配置Celery:
CELERY_BROKER_URL = os.environ.get('REDIS_URL')
CELERY_RESULT_BACKEND = os.environ.get('REDIS_URL')
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True

创建芹菜任务

在您的 Django 应用程序中,在tasks.py 中定义任务:

# myapp/tasks.py
from celery import shared_task

@shared_task
def my_scheduled_task():
    print("This task runs every every day.")

创建 Docker 配置

  • 为 Django 的 api 创建一个 Dockerfile(名为:Dockerfile.myapi):
FROM python:3.8-alpine3.15

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

COPY requirements.txt /app

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 9000

CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "myproject.wsgi:application"]
  • 为 celery 创建一个 Dockerfile(名为:Dockerfile.myjob)
FROM python:3.8-alpine3.15

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app
COPY requirements.txt /app
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app

CMD ["celery", "-A", "myproject", "worker", "--loglevel=info", "--concurrency=4", "-E", "-B"]
  • 创建一个requirements.txt文件来列出您的依赖项:
Django==4.2
djangorestframework==3.14.0
celery==5.3.1
redis==5.0.0
  • 创建 docker-compose.yml 文件来管理服务:
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.myapi
    container_name: myapp_api
    ports:
      - 7000:7000
    env_file:
      - .env

  celery:
    build:
      context: .
      dockerfile: Dockerfile.myjob
    container_name: myapp_job
    depends_on:
      - app
    env_file:
      - .env
  • 创建一个 .env 文件并向其中添加 Redis URL 值:
REDIS_URL=

构建并运行 Docker 容器

  • 构建并运行 Docker 镜像:
docker-compose up --build

这将启动您的 Django 应用程序,以及 Celery 工作线程和 Celery 节拍调度程序。

验证 Cron 作业

您的 Celery 任务现在应该根据您定义的时间表运行。您可以查看指定时间的日志来确认任务正在执行。

结论

使用 Celery、Docker 和 Redis 在 Django 中运行 cron 作业为管理后台任务提供了强大且可扩展的解决方案。 Docker 可确保您的应用程序在不同环境中一致运行,从而使部署更加轻松。通过执行上述步骤,您可以高效地自动化任务并轻松管理您的 Django 项目。

版本声明 本文转载于:https://dev.to/engrmark/running-a-cron-job-in-django-using-celery-and-docker-238d?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 高级 T:依赖参数、推断联合以及 Twitter 上的健康交互。
    高级 T:依赖参数、推断联合以及 Twitter 上的健康交互。
    每次我用 TypeScript 写成 Foo 时,我都会感受到失败的沉重。 在一种情况下,这种感觉特别强烈:当函数采用的参数取决于哪个 "mode" 处于活动状态时。 通过一些示例代码更清晰: type Provider = "PROVIDER A" | "PR...
    编程 发布于2024-11-07
  • 如何创建人力资源管理解决方案
    如何创建人力资源管理解决方案
    1. Understanding the Basics of Frappe and ERPNext Task 1: Install Frappe and ERPNext Goal: Get a local or cloud-based instance of ERP...
    编程 发布于2024-11-07
  • 从周五黑客到发布:对创建和发布开源项目的思考
    从周五黑客到发布:对创建和发布开源项目的思考
    从周五补丁破解到发布:对创建和发布开源项目的思考 这是针对初学者和中级开发人员的系列的一部分,通过将他们的想法作为开源项目发布或引起兴趣。 这些想法是有偏见的和个人的。计划发布更多文章。通过分享一些思考,我希望能启发你做自己的项目 思考(此) 作为 Java 开发人员学习 Go l...
    编程 发布于2024-11-07
  • 可以使用 constexpr 在编译时确定字符串长度吗?
    可以使用 constexpr 在编译时确定字符串长度吗?
    常量表达式优化:可以在编译时确定字符串长度吗?在优化代码的过程中,开发人员尝试计算使用递归函数在编译时计算字符串文字的长度。此函数逐字符计算字符串并返回长度。初始观察:该函数似乎按预期工作,在运行时返回正确的长度并生成表明计算发生在编译时的汇编代码。这就提出了一个问题:是否保证length函数会在编...
    编程 发布于2024-11-07
  • 在 Raspberry Pi 上运行 Discord 机器人
    在 Raspberry Pi 上运行 Discord 机器人
    Unsplash 上 Daniel Tafjord 的封面照片 我最近完成了一个软件工程训练营,开始研究 LeetCode 的简单问题,并觉得如果我每天都有解决问题的提醒,这将有助于让我负起责任。我决定使用按 24 小时计划运行的不和谐机器人(当然是在我值得信赖的树莓派上)来实现此操作,该机器人将执...
    编程 发布于2024-11-07
  • 解锁 JavaScript 的隐藏宝石:未充分利用的功能可提高代码质量和性能
    解锁 JavaScript 的隐藏宝石:未充分利用的功能可提高代码质量和性能
    In the ever-evolving landscape of web development, JavaScript remains a cornerstone technology powering countless large-scale web applications. While...
    编程 发布于2024-11-07
  • 为什么通过非常量指针修改“const”变量看起来有效,但实际上并没有改变它的值?
    为什么通过非常量指针修改“const”变量看起来有效,但实际上并没有改变它的值?
    通过非常量指针修改 const在 C 中,const 变量一旦初始化就无法修改。但是,在某些情况下,const 变量可能会被更改。考虑以下代码:const int e = 2; int* w = (int*)&e; // (1) *w = 5; ...
    编程 发布于2024-11-07
  • Android - 将 .aab 文件上传到 Play 商店时出错
    Android - 将 .aab 文件上传到 Play 商店时出错
    如果您遇到此错误,请按照以下步骤操作以确保与您的包名称和签名密钥保持一致: 确保 app.json 文件中的包名称与您第一次上传 .aab 文件时使用的包名称匹配。 "android": { "permissions":["CAMERA","READ_EXTERNAL_STORAGE...
    编程 发布于2024-11-07
  • 如何使用 PHP 将 HTML 转换为 PDF
    如何使用 PHP 将 HTML 转换为 PDF
    (适用于 Windows 的指南。不适用于 Mac 或 Linux) (图片来源) 在 PHP 中将 HTML 转换为 PDF 的方法不止一种。您可以使用Dompdf或Mpdf;但是,这两个库的执行方式有所不同。 注意:本文中并未包含所有解决方案。 要使用这两个库,您将需要 Composer。 ...
    编程 发布于2024-11-07
  • C++ 会拥抱垃圾收集吗?
    C++ 会拥抱垃圾收集吗?
    C 中的垃圾收集:实现和共识的问题虽然有人建议 C 最终会包含垃圾收集器,但它仍然是争论和持续发展的主题。要理解其中的原因,我们必须深入研究迄今为止阻碍其纳入的挑战和考虑因素。实现复杂性向 C 添加隐式垃圾收集是一个非-琐碎的任务。该语言的低级性质和对指针的广泛支持带来了重大的技术障碍。实施问题的范...
    编程 发布于2024-11-07
  • 如何有条件地删除 MySQL 中的列?
    如何有条件地删除 MySQL 中的列?
    使用 MySQL ALTER 进行条件列删除MySQL 中的 ALTER 命令提供了一种从表中删除列的简单方法。但是,当指定列不存在时,其传统语法 (ALTER TABLE table_name DROP COLUMN column_name) 会引发错误。对于 MySQL 版本 4.0.18,没有...
    编程 发布于2024-11-07
  • 你应该了解的现代 CSS 样式 4
    你应该了解的现代 CSS 样式 4
    TL;DR: 本博客使用代码示例来探索 Web 开发的五种最佳 CSS 样式和功能:容器查询、子网格、伪类、逻辑属性和实验室颜色空间。它们增强响应能力、简化布局并提高设计一致性。 层叠样式表 (CSS) 是一种众所周知的用于设计网页样式的语言。使用 CSS,您可以通过添加空格来自定义 HTML 元素...
    编程 发布于2024-11-07
  • 箭头函数或父作用域何时定义函数的参数?
    箭头函数或父作用域何时定义函数的参数?
    ES6 箭头函数中的参数:官方说明在 ES6 箭头函数中,arguments 关键字的行为一直是争论的话题。一些浏览器和平台(例如 Chrome、Firefox 和 Node)偏离了最初的 TC39 建议,引发了对该规范正确解释的质疑。根据官方 ES6 规范,箭头函数没有其自身的定义。自己的参数在其...
    编程 发布于2024-11-07
  • 根据您提供的内容,以下是一些采用问题格式的潜在文章标题:

* 加载数据本地内文件访问被拒绝:如何排除和修复错误? 
* 为什么要加载数据LOCA
    根据您提供的内容,以下是一些采用问题格式的潜在文章标题: * 加载数据本地内文件访问被拒绝:如何排除和修复错误? * 为什么要加载数据LOCA
    LOAD DATA LOCAL INFILE 访问被错误拒绝:不允许使用的命令当利用 MySQL 的 LOAD DATA INFILE 执行 PHP 脚本时,它可能会遇到错误“用户访问被拒绝...(使用密码:是)”。常见的解决方法是切换到 LOAD DATA LOCAL INFILE,尽管这可能会导...
    编程 发布于2024-11-07
  • 如何在 Python 中检查文本文件是否为空?
    如何在 Python 中检查文本文件是否为空?
    确定文本文件是否为空在编程领域,通常需要确定特定文件是否包含任何数据或无效。本文深入探讨了这样一个问题:“我们如何确定文本文件是否为空?”Python 作为一种多功能编程语言,为这个问题提供了一个简单的解决方案。通过利用 os.stat() 函数,我们可以检索有关文件的属性数组,包括其大小。查询答案...
    编程 发布于2024-11-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3