欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

django社交类程序笔记(8)Celery异步任务

程序员文章站 2022-04-19 20:44:33
...

celery 异步任务,耗时操作可以使用。
同步就是一个任务一个任务按顺序做,异步就是做一会A,做一会B,可以换着做任务。
django社交类程序笔记(8)Celery异步任务
任务模块 Task
包含异步任务和定时任务。其中, 异步任务通常在业务逻辑中被触发并发往任务队列, ⽽定时任务由 Celery Beat 进程周期性地将任务发往任务队列。
消息中间件 Broker
Broker, 即为任务调度队列, 接收任务⽣产者发来的消息(即任务), 将任务存⼊队列。Celery 本身不提供队列服务, 官⽅推荐使⽤ RabbitMQ 和 Redis 等。
任务执⾏单元 Worker
Worker 是执⾏任务的处理单元, 它实时监控消息队列, 获取队列中调度的任务, 并执⾏它。
任务结果存储 Backend
Backend ⽤于存储任务的执⾏结果, 以供查询。同消息中间件⼀样, 存储也可使⽤
RabbitMQ, Redis 和 MongoDB 等。
可以参考这里
这里涉及celery问题和redis,及装饰器知识点,
本项目继续:
在主项目中创建文件夹worker,新建__init__.py和config.py文件
init.py中添加代码:

import os

from celery import Celery


# 设置环境变量,加载django的setting
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'spiter.settings')  # 可以复制wsgi.py

# 创建Celery Application
celery_app = Celery('spiter')
celery_app.config_from_object('worker.config')
celery_app.autodiscover_tasks()

def call_by_worker(func):
    """将任务在Celery中异步执行"""
    task = celery_app.task(func)
    return task.delay

config.py中添加代码:

broker_url = 'redis://127.0.0.1:6379/0'
broker_pool_limit = 1000 # Borker 连接池,默认是10
timezone = 'Asia/Shanghai'
accept_content = ['pickle', 'json']
task_serializer = 'pickle'
result_expires = 3600 # 任务过期时间
result_backend = 'redis://127.0.0.1:6379/0'
result_serializer = 'pickle'
result_cache_max = 10000 # 任务结果最⼤缓存数量
worker_redirect_stdouts_level = 'INFO'

当发送短信时,会交给celery来做,不是django做。

缓存,在logic.py中增加缓存如下:

from django.core.cache import cache

...

@call_by_worker
def send_verify_code(phonenum):  # 手机号拼进来
    vcode = gen_verify_code()  # 验证码
    key = 'VerifyCode-%s' % phonenum  # 手机号前加前缀,表示这个手机号功能。
    cache.set(key, vcode)
   ...
    return response

现在考虑如何设置验证码过期,比如60秒后验证码失效,
小功能:ipython中可以输入cache.set?会输出参数
输入两个问号会输出源代码cache.set??

可以使用缓存的过期时间来让验证码过期。将上面代码cache.set行修改如下

cache.set(key, vcode,60)

附加面试小课堂:

nginx
静态文件处理,也可以代理动态文件,动静分离的目的
反向代理,不让用户知道服务器。
负载均衡:将任务均匀分发给上百台服务器
uWSGI:协议转化,提升性能,内部集合了一些协程,使用C语言写的。
gunicorn:某些方面比uWSGI好。
nonlocal
global 全局变量

a = 123
def foo(x):
	a=a+x
	return a 
foo(321)

上面会报错,python作用域。修改如下:

a = 123
def foo(x):
	global a
	a=a+x
	return a 
foo(321)
def foo():
	x = 123
	def bar(y):
		x = x+y
		return x
	return bar

返回一个函数bar,
bar = foo(321)还是会报上面同样的错误,这里不能使用global,因为x不是全局变量,但是可以使用nonlocal告诉函数这个x是非本层次的x,但还是局部变量。

def foo():
	x = 123
	def bar(y):
		nonlocal x
		x = x+y
		return x
	return bar
bar = foo()
bar(321)

在ipython 中定义一个数字后

b = 123
b.按table会出现方法属性

一个函数后可以比如加点和下划线按table会出现方法属性。

bar._

bar.closure[0] 这就是闭包,函数和变量打包在一起存在的。
装饰器底层也是一种闭包,装饰完的函数就是闭包。
比如装饰器装饰了函数bar,
使用bar.__name__可以看到它的名字叫wrap