Celery知识

最后

不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~

给大家准备的学习资料包括但不限于:

Python 环境、pycharm编辑器/永久激活/翻译插件

python 零基础视频教程

Python 界面开发实战教程

Python 爬虫实战教程

Python 数据分析实战教程

python 游戏开发实战教程

Python 电子书100本

Python 学习路线规划

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

1、安装:pip install celery
2、写个py文件 demo.py

from celery import Celery
import time
broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery('app', broker=broker, backend=backend)
# 写任务---》写函数---》必须用 @app.task 装饰---》装饰后,就变成了celery的任务了
@app.task
def hello():
    time.sleep(2)  # 模拟任务延迟
    return 'hello world'
@app.task
def add(a, b):
    time.sleep(3)
    return a + b

3、其他程序中,提交任务

res=add.delay(4,5)
print(res)

4、 启动worker—worker启动可以再靠前
 win运行:
        pip3 install eventlet
        celery -A demo worker -l info -P eventlet

非win运行:mac linux
        celery -A demo  worker -l info

5、查询结果
—直接取redis中查
—使用代码查询

from demo import app
from celery.result import AsyncResult
id = '17bf03ad-a1e6-49d1-a182-794bd3e96b74'
if __name__ == '__main__':
        a = AsyncResult(id=id, app=app)
        if a.successful():
            result = a.get() # hello world
            print(result)
        elif a.failed():
            print('任务失败')
        elif a.status == 'PENDING':
            print('任务等待中被执行')
        elif a.status == 'RETRY':
            print('任务异常后正在重试')
        elif a.status == 'STARTED':
            print('任务已经开始被执行')

celery包结构

包结构 目录如下:

–celery_task
                    --celery.py
                    --user_task.py
                    --order_task.py
                    --goods_task.py
    
-其他程序中提交任务: add_task_package.py
-其他程序中查询结果:get_result_package.py
###具体步骤

# celery.py  
from celery import Celery
#######1 实例化得到对象 ##########
broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery('app', broker=broker, backend=backend,include=['celery_task.order_task','celery_task.user_task'])
#######2 写任务 ##########以后各种类型任务,单独写在py文件中
# order_task.py   user_task.py 
# order_task.py
import time
from .celery import app
@app.task
def cancel_order(order_id):
    time.sleep(2)
    return '订单:%s取消成功' % order_id
# user_task.py
import time
from .celery import app
@app.task
def send_sms(phone, code):
    time.sleep(1)
    return '手机号:%s,发送验证码:%s,成功' % (phone, code)
######## 3 其他程序,提交任务 ##############################
from celery_task.user_task import send_sms
res=send_sms.delay('1893424323',8888)
print(res)
4 启动worker########## 在包的一层,执行包,不需要具体到某个py文件了

win运行:pip3 install eventlet
        A celery_demo 包名----因为他会去包下找 celery.py 中得app执行
        celery -A celery_task worker -l info -P eventlet

非win运行:mac linux
        celery -A celery_task  worker -l info

#####5 查询结果#####
# 使用代码,查询结果
from celery_task.celery import app
from celery.result import AsyncResult

id = '46b26c73-62ae-403c-ba62-e469f2f8c69f'
if __name__ == '__main__':
    a = AsyncResult(id=id, app=app)
    if a.successful():
        result = a.get() # hello world
        print(result)
    elif a.failed():
        print('任务失败')
    elif a.status == 'PENDING':
        print('任务等待中被执行')
    elif a.status == 'RETRY':
        print('任务异常后正在重试')
    elif a.status == 'STARTED':
        print('任务已经开始被执行')
celery实现异步任务,定时任务,延迟任务

异步任务:

任务名.delay(传参数)

延迟任务—延迟多长事件干事

点右键执行,work运行

# 链接上面任务二的order函数
from celery_task.order_task import cancel_order
from datetime import datetime, timedelta

# atetime.utcnow() 当前utc时间
eta = datetime.utcnow() + timedelta(seconds=15)
res = cancel_order.apply_async(args=['10001',], eta=eta)  # 订单+15s 后执行这个任务
print(res)

定时任务–一定要启动beat

1、 在celery.py 中写

# 链接上面任务二的user_task函数
# 时区
app.conf.timezone = 'Asia/Shanghai'
# 不使用UTC时间
app.conf.enable_utc = False
# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'send_sms': {
        'task': 'celery_task.user_task.send_sms',  #  执行的任务函数 
        'schedule': timedelta(seconds=3),    # 每隔三秒钟干
        # 'schedule': crontab(hour=8, day_of_week=1),  # 每周一早八点
        'args': ('1896388888', '6666'),     # 传参数,手机号\验证码
    }
}

2、启动worker:celery -A celery_task worker -l info -P eventlet
3、启动beat(每个一段时间,就提交任务):celery -A celery_task beat  -l info

4、等待即可

django中使用celery

两种方案:

-通用方案:自己封装
    -django-celery–》app—》创建出一些表

自己封装的通用方案:

1、把封装的包:celery_task 复制到项目中
2、在django中使用celery.py 中必须加入
    os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘luffy_api.settings.dev’)
    3 写任务,启动worker
    4 在django的视图类中,异步调用即可

# celery_task/celery.py
from celery import Celery
import os

# 任务里使用django的东西:缓存,表模型。。。必须加入
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')

# 1 实例化得到对象
broker = 'redis://127.0.0.1:6379/0'
backend = 'redis://127.0.0.1:6379/1'
app = Celery('app', broker=broker, backend=backend, include=['celery_task.order_task', 'celery_task.user_task'])

# 2 写任务,以后各种类型任务,单独写在py文件中

# 定时任务
app.conf.timezone = 'Asia/Shanghai'    # 时区
app.conf.enable_utc = False    # 不使用UTC

# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab

app.conf.beat_schedule = {
}

# celery_task/user_task.py
import time
from .celery import app
from libs.send_information import common_send_sms

@app.task
def send_sms(phone, code):
    res = common_send_sms(code, mobile=phone)
    if res:
        return '短信发送成功:%s' % phone
    else:
        return '短信发送失败:%s' % phone


# user/views.py
    # 发送短信接口
    @action(methods=['get'], detail=False, url_path='send_information')
    def send_sms(self, request):
        try:
            mobile = request.query_params['mobile']  # 取的手机号放在请求地址栏中
            code = get_code()  # 生成验证码
            cache.set('sms_code_%s' % mobile, code, 61)  # 放在缓存中,以手机号做区
            # 异步发送短信--不管是否成功--如果不成功,用户再发一次即可
            # t = Thread(target=common_send_sms, args=[code, mobile])
            # t.start()  # 启动线程发送短信

            # celery异步发送短信
            send_sms.delay(mobile, code)
            return APIResponse(msg='短信已发送')

        except MultiValueDictKeyError as e:
            raise APIException(detail='手机号必须携带')
        except Exception as e:
            raise APIException(detail=str(e))

双写一致性(缓存问题)

轮播图加缓存

出现问题:banner表中数据变了,缓存不会变
    mysql和redis数据不一致: mysql和redis双写一致性

双写一致性的解决方案:

1、mysql修改—删缓存
    2、mysql修改—改缓存
    3、定时更新—每个5s,更新一次缓存
             先删缓存,在更新mysql
            先改缓存,再更新mysql

轮播图的接口—使用定时更新,解决双写一致性问题

# celery_task/home_task.p
import time
from .celery import app
from home.models import Banner
from django.conf import settings
from home.serializer import BannerSerializer
from django.core.cache import cache


@app.task
def update_banner():
    # 1 获取所有轮播图数据
    queryset = Banner.objects.all().filter(is_delete=False, is_show=True).order_by('orders')[:settings.BANNER_COUNT]
    # 2 序列化
    ser = BannerSerializer(instance=queryset, many=True)
    # ser.data
    # 2.1 把服务端前缀拼接上
    for item in ser.data:
        # media/banner/banner1.png,
        item['image'] = settings.BACKEND_URL + item['image']
    # 3 放到缓存
    cache.set('banner_list', ser.data)
    return '更新成功'
# celery.py
app = Celery('app', broker=broker, backend=backend, include=['celery_task.order_task', 'celery_task.user_task','celery_task.home_task'])

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

启动worker:celery -A celery_task worker -l info -P eventlet

启动beat:celery -A celery_task beat  -l info
# 以后尽管改 mysql数据,最多3分钟就会更新到最新了

异步秒杀方案

秒杀功能:

并发量要高:承载住很多用户同时操作
                订单表
                扣减库存
            效率要高

同步秒杀

假设秒杀需要10s钟,项目并发量是3,总共5个商品要秒杀
    10s内,只有3个人能进入到系统,并且开始秒杀

# 前端
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/seckill',
    name: 'seckill',
    component: SeckillView
  },
]
<template>
  <div>
    <Header></Header>
    <div style="padding: 50px;margin-left: 100px">
      <h1>Go语言课程</h1>
      <img src="http://photo.liuqingzheng.top/2023%2002%2022%2021%2057%2011%20/image-20230222215707795.png"
           height="300px"
           width="300px">
      <br>
      <el-button type="danger" @click="handleSeckill" v-loading.fullscreen.lock="fullscreenLoading">秒杀课程</el-button>
    </div>


    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>


    <Footer></Footer>

  </div>
</template>

<script>
import Header from '@/components/Header'
import Footer from '@/components/Footer'

export default {
  name: "SckillView",
  data() {
    return {
      fullscreenLoading: false,
      task_id: '',
      t: null,
    }
  },
  methods: {
    // ##############同步秒杀##############
    // handleSeckill() {
    //   this.fullscreenLoading = true;
    //   this.$axios({
    //     url: '/user/seckill/seckill/',
    //     method: 'POST',
    //     data: {
    //       course_id: '99'
    //     }
    //   }).then(res => {
    //     this.fullscreenLoading = false;
    //     this.$message.success(res.msg)
    //   }).catch(res => {
    //     this.fullscreenLoading = false;
    //     this.$message.error(res)
    //   })
    // }
    // ##############同步秒杀##############


    // ##############异步秒杀##############
    handleSeckill() {
      this.fullscreenLoading = true;
      this.$axios({
        url: '/user/seckill/seckill/',
        method: 'POST',
        data: {
          course_id: '99'
        }
      }).then(res => {
        // 在排队,转圈的,还需要继续显示

最后

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值