异步方案redis和Celery

                    


在这里插入图片描述
在这里插入图片描述
说明:

  1. 生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
  2. 由美多商城生成发送短信消息,缓存到消息队列中,消费者读取消息队列中的发送短信消息并执行。

Celery工具介绍和使用

思考:

1.消费者取到消息之后,要消费掉(执行任务),需要我们去实现。
2.任务可能出现高并发的情况,需要补充多任务的方式执行。
3.耗时任务很多种,每种耗时任务编写的生产者和消费者代码有重复。
4.取到的消息什么时候执行,以什么样的方式执行。

结论:

实际开发中,可以借助成熟的工具 Celery 来完成。
有了 Celery,在使用生产者消费者模式时,只需要关注任务本身,极大的简化了开发流程.

介绍:

celery 是一个简单、灵活且可靠、处理大量消息的分布式系统,可以在一台或者多台机器上运行.

特点:

  1. 单个 Celery 进程每分钟可处理数以百万计的任务.

  2. 通过消息进行通信,使用消息队列( 中间人或broker )在生产者和消费者之间进行协调。

1、安装

# 安装到虚拟环境, 你懂得~

官方文档

2、创建实例并且配置

①、定义Celery包:celery_tasks

②、创建Celery实例:celery_tasks包中创建main.py文件,并添加如下代

# 从你刚刚下载的包中导入 Celery 类
from celery import Celery


# 利用导入的 Celery 创建对象
celery_app = Celery('meiduo')

注意:这里的“meiduo”字符串可以使用别的字符串替换

③、加载Celery配置:在celery_tasks包中加一个config.py文件,在这个文件中指定一下 消息队列(中间人)的位置

# 如果使用 redis 作为中间人
# 需要这样配置:
# 1.
broker_url='redis://127.0.0.1:6379/3'



# 如果使用别的作为中间人, 例如使用 rabbitmq
# 则 rabbitmq 配置如下:
# 2.
broker_url= 'amqp://用户名:密码@ip地址:5672'

# 例如: 
# meihao: 在rabbitq中创建的用户名, 注意: 远端链接时不能使用guest账户.
# 123456: 在rabbitq中用户名对应的密码
# ip部分: 指的是当前rabbitq所在的电脑ip
# 5672: 是规定的端口号
# 3.
broker_url = 'amqp://meihao:123456@172.16.238.128:5672'


说明:上面的配置, 选择一个即可

④、config添加到创建的对象中celery_tasks.main.py

from celery import Celery

celery_app = Celery('meiduo')

# 将刚刚的 config 配置给 celery
# 里面的参数为我们创建的 config 配置文件:
celery_app.config_from_object('celery_tasks.config')
View Code

3、定义任务

  • 注册任务
  1. 在 celery_tasks 包下, 再创建一个包, 名字随意
  2. 在里面添加一个 tasks.py 文件,文件名规定死了
  3. 在 celery_tasks.main.py 报备刚刚创建的文件:
from celery import Celery

celery_app = Celery('meiduo')

celery_app.config_from_object('celery_tasks.config')

# 让 celery_app 自动捕获目标地址下的任务: 
# 就是自动捕获 tasks
celery_app.autodiscover_tasks(['celery_tasks.sms'])
View Code
  • 实现任务
  1. 已经报备之后, 在 tasks.py 中添加具体的内容
  2. 在 celery_tasks.sms.tasks.py 文件中添加如下代码:
from celery_tasks.main import celery_app

@celery_app.task(name='ccp_send_sms_code')
def ccp_send_sms_code(mobile, sms_code):
    '''该函数就是一个任务, 用于发送短信'''
    result = CCP().send_template_sms(mobile,[sms_code, 5],1)
    return result
View Code

注意:

  • 添加完该函数后, CCP() 是调用我们项目中的 libs.yuntongxun 中的文件, 但是, 真实的开发环境有可能会把 celery_tasks 单独拿到某一个电脑上独立执行, 会和美多商城项目分开. 所以那时就找不到 libs
  • 把 yuntongxun 复制一份, 放到 celery_tasks 下面, 拿走的时候, 直接调用走就可以.

如图所示

在这里插入图片描述

4、调用任务

# 1.导包ccp_send_sms_code
from celery_tasks.sms.tasks import ccp_send_sms_code

# 原来的写法:
# CCP().send_template_sms(mobile, [sms_code, 5], 1)

# 改为现在的写法, 注意: 这里的函数,调用的时候需要加: .delay()
ccp_send_sms_code.delay(mobile, sms_code)
View Code

5、启动消费者(celery充当)

# 想要启动 celery 服务, 调用下面的命令行: 
cd ~/projects/meiduo_project/meiduo_mall

celery -A celery_tasks.main worker -l info

参数说明:

  1. celery : 调用 celery 命令
  2. -A : 作用是指定要启动的文件, 这个参数后面的文件会被执行.
  3. worker : 启动的对象是 worker, 工人, 干活的人
  4. -l : 指日志打印等级, 一般日志都是通知形式的, 即: info 级别
  5. 启动前必须开启redis服务

补充:celery worker的工作模式

默认是进程池方式:

进程数以当前机器的CPU核数为参考,每个CPU开四个进程

指定进程数:

celery worker -A proj --concurrency=4

改变进程池方式为协程方式:

celery worker -A proj --concurrency=1000 -P eventlet -c 1000

# 安装 eventlet 模块
$ pip install eventlet -i https://pypi.tuna.tsinghua.edu.cn/simple

# 启用 Eventlet 池
$ celery -A celery_tasks.main worker -l info -P eventlet -c 1000


posted on 2020-09-04 11:22  yycnblog  阅读(442)  评论(2)    收藏  举报

导航