celery介绍、celery快速使用、celery异步任务,延迟任务,定时任务、双写一致性

一、celery介绍

它是一个分布式异步框架

celery有什么用?

1.完成异步任务:可以提高项目的并发量,之前开启线程,现在使用celery,

2.完成延迟任务

3.完成定时任务

架构

1.消息中间件:broker 提交的任务(函数)都放到这里,celery本身不提供中间件,需要借助于第三方:redis,rabbitmq

2.任务执行单元:worker,真正执行任务的地方,一个个进程,执行函数

3.结果存储:backend,函数return的结果存储在这里,celery本身不提供结果存储,借助于第三方:redis,数据库,rabbitmq

image

celery快速使用

1.celery官网:http://www.celeryproject.org/

2.介绍:Celery is a project with minimal funding, so we don’t support Microsoft Windows. Please don’t open any issues related to that platform(不支持windows,如果有任何问题不要去平台问)

3.celery是独立的服务

    1)可以不依赖任何服务器,通过自身命令,启动
    2)celery服务为其他项目服务提供异步解决任务需求的

    注意:会有两个服务同时运行,一个是项目服务,一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求

    例如:人是一个独立运行的服务(django) | 医院也是一个独立运行的服务(celery)
        正常情况下,人可以完成所有健康情况的动作,不需要医院的参与;但当人生病时,就会被医院接收,解决人生病问题
        人生病的处理方案交给医院来解决,所有人不生病时,医院独立运行,人生病时,医院就来解决人生病的需求

安装

pip install celery

pip install eventlet

使用步骤

1.新建一个包:celery_task

2.写一个celery.py:实例化得到app对象,写函数,任务,注册celery的任务

3.再别的程序中:提交任务--->执行异步任务,把任务提交到celery中
    add.delay
4.在包里新建user_task 编写用户相关任务

5.在包里新建home_task 编写首页相关任务

6.其他程序,提交任务

7.启动worker---> 可以先启动,在提交任务之前--->查看路劲是否在包所在的路劲下
    win:
        celery -A celery_task worker -l info -P eventlet    # 5.x及其之后用这个
        celery worker -A main -l info -P eventlet  # 4.x及之前用这个
    linux、mac:
        celery worker -A main -l info
        celery -A main worker -l info

8.查看任务执行的结果(backend)
    直接看
    通过代码查看
        from main import app
        from celery.result import AsyncResult
        id = '7bef14a0-f83e-4901-b4d8-e47aaac09b39'
        if __name__ == '__main__':
            res = AsyncResult(id=id, app=app)
            if res.successful():
                result = res.get()  #7
                print(result)
            elif res.failed():
                print('任务失败')
            elif res.status == 'PENDING':
                print('任务等待中被执行')
            elif res.status == 'RETRY':
                print('任务异常后正在重试')
            elif res.status == 'STARTED':
                print('任务已经开始被执行')

celery包结构

celery_task
    -__init__.py
    -celery.py
    -user_task.py
    -home_task.py
add_task.py
get_result.py

celery异步任务,延迟任务,定时任务

"""异步任务"""
    任务.delay(参数,参数)
"""延迟任务"""
    任务.apply_async(args=[参数,参数],eta=时间对象(utc时间))
"""定时任务"""
    # 定时任务配置
        -1 app的配置文件中配置 
            app.conf.beat_schedule = {
                'send_sms_task': {
                    'task': 'celery_task.user_task.send_sms',
                    'schedule': timedelta(seconds=5),
                    # 'schedule': crontab(hour=8, day_of_week=1),  # 每周一早八点
                    'args': ('1897334444', '7777'),
                },
                'add_task': {
                    'task': 'celery_task.home_task.add',
                    'schedule': crontab(hour=12, minute=10, day_of_week=3),  # 每周一早八点
                    'args': (10, 20),
                }
            }
        -2 启动worker :干活的人
            celery -A celery_task worker -l info -P eventlet
        -3 启动beat :提交任务的人
            celery -A celery_task beat -l info

双写一致性

首页轮播图接口,加缓存

这么做的好处就是提交了接口的响应速度,提高了并发量

class BannerView(GenericViewSet, CommonListModelMixin):
    queryset = Banner.objects.all().filter(is_delete=False, is_show=True).order_by('orders')[:settings.BANNER_COUNT]
    serializer_class = BannerSerializer

    def list(self, request, *args, **kwargs):
        result = cache.get('banner_list')
        if result:  # 缓存里有
            print('走了缓存,速度很快')
            return APIResponse(result=result)
        else:
            # 去数据库拿
            print('走了数据库,速度慢')
            res = super().list(request, *args, **kwargs)
            result = res.data.get('result')  # {code:100,msg:成功,result:[{},{}]}
            cache.set('banner_list', result)
            return res

加了缓存,如果mysql数据变了,由于请求的1都是缓存的数据,导致mysql和redis的数据不一致

双写一致性问题

1.修改mysql数据库,删除缓存,缓存的修改是在后

2.修改数据库,修改缓存,缓存的修改是在后

3.定时更新缓存,针对实时性不是很高的接口适合定时更新

给首页轮播图接口加入了缓存,出现了双写一致性问题,使用定时更新来解决双写一致性的问题(会存在不一致的情况,我们可以忽略)--->定时任务,celery的定时任务
celery.py

from celery import Celery

# django 中集成celery,需要加入
import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
import django

django.setup()

backend = 'redis://127.0.0.1:6379/1'
broker = 'redis://127.0.0.1:6379/0'
app = Celery(__name__, broker=broker, backend=backend, include=['celery_task.home_task', 'celery_task.user_task'])

# 写定时任务
# app的配置项
# 时区  app.conf  所有的配置字典,默认的
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

## 编写定时任务
from datetime import timedelta

app.conf.beat_schedule = {
    'update_banner': {
        'task': 'celery_task.home_task.update_banner',
        'schedule': timedelta(seconds=50),
        'args': (),
    }
}

home_task.py

from celery import Celery

# django 中集成celery,需要加入
import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
import django

django.setup()

backend = 'redis://127.0.0.1:6379/1'
broker = 'redis://127.0.0.1:6379/0'
app = Celery(__name__, broker=broker, backend=backend, include=['celery_task.home_task', 'celery_task.user_task'])

# 写定时任务
# app的配置项
# 时区  app.conf  所有的配置字典,默认的
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

## 编写定时任务
from datetime import timedelta

app.conf.beat_schedule = {
    'update_banner': {
        'task': 'celery_task.home_task.update_banner',
        'schedule': timedelta(seconds=50),
        'args': (),
    }
}

# 启动django
# 启动worker
# 启动beat

# 第一次访问:查的数据库,放入了缓存
# 以后再访问,走缓存
# 一旦mysql数据改了,缓存可能不一致
# 当时我们定时更新,最终保持了一致
posted @   张张张张冉  阅读(211)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示