上传文件、异步、初始化脚本

面试题:

项目中的静态文件处理(JS/CSS/image) 自己在机房内优化的方法: 1. Nginx/lighttpd(lighty-douban):Nginx 处理静态资源速度非常快,并且自身还带有缓存。 2. 80: Nginx -> {server config} -> django:8080 -> Static : folders -> 云存储

你了解CDN吗?能讲讲原理么?

扩展:如何更换CDN上的图片?改名大法

  1. 请求加参数:

    1. abc.jpg
    2. abc.jpg?20191011111042asdflj2
    3. abc.jpg?20191011111043
  2. 改名

    1. abc_201910111042.jpg
    2. abc_md5.jpg

## 七牛云接入

  1. 注册七牛云账号
  2. 创建存储空间:Bucket -> 有独立的域名,可以访问
  3. 获取相关配置
    • AccessKey:从个人中心-密钥管理里获得
    • SecretKey:从个人中心-密钥管理里获得
    • Bucket_name:我们自己新建的存储空间的名字
    • Bucket_URL:建好的新存储空间的访问url
  4. 安装 qiniu SDK:pip install qiniu
  5. 根据接口文档进行接口封装
  6. 按照需要将上传、下载接口封装成异步任务
  7. 程序处理流程
    1. 服务端上传方式
      1. 用户图片先上传到我们的服务器上
      2. 然后,我们的程序再调用七牛云的api,将图片上传到七牛云
      3. 上传成功后,拼接 avatar 的图片 url 地址:
        1. 七牛云的Bucket_URL/filename,将 avatar 的图片 url 存入数据库
    2. 客户端直传
      1. 客户端图片直接上传到云服务
      2. 客户端将图片地址告诉服务端,服务端更新数据库
      3. 其实存在一个安全隐患
        1. 客户端先从服务端获取token,再上传

代码示例 使用了celery

#上传图片
def user_avatar(request):
    #1.存下来
    # 定义上传后保存的文件名
    file_name =f'avatar-{request.user.id}.jpg'
    # 上传后保存的路径
    file_path = f'{settings.BASE_DIR}/static/{file_name}'
    #接收上传文件内容
    f = request.FILES['avatar']

    with open(file_path,'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    print('save local ok.')
    user_id = request.user.id
    #delay很重要!!!
    upload_qiniu.delay(file_name, file_path, user_id)
    return  render_json('已经放入celery-redis队列中')

#这一步用异步celery
@celery_app.task
def upload_qiniu(file_name, file_path, user_id):
    # 2.调用七牛云sdk上传
    # 需要填写你的 Access Key 和 Secret Key 需要修改 
    access_key = 'KXfx2ZiBP311HkZZ8l8JHCmqlqPTJCK2sraihexx'
    secret_key = 'pe5svTTUAJQoUPhppsf0Gg9wbEJiYahnRMAy1rxx'
    # 要上传的空间
    bucket_name = 'liu'
    # 要上传的域名
    bucket_domain = ' liu.s3-cn-south-1.qiniucs.com'
    # 构建鉴权对象
    q = Auth(access_key, secret_key, )
    token = q.upload_token(bucket_name, file_name, 3600)
    ret, info = put_file(token, file_name, file_path)
    print(info)
    #断言
    assert ret['key'] == file_name
    assert ret['hash'] == etag(file_path)
    print('save qiniu ok.')
    avatar_url = f'{bucket_domain}/{file_name}'
    # 3.更新用户的avatar
    user = User.objects.get(id=user_id)
    # user = request.user # request 无法传 所以改为user_id
    user.avatar = avatar_url
    user.save()

    return  True

异步任务

Celery 及异步任务的处理

  1. 通用的异步框架的原理

  2. 核心队列:消息队列

  3. 客户端:异步端

  4. 生产者:消费者

  5. 发布者:订阅者

  6. 发送者:接收者

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFOxnBJs-1577967577874)(/Users/zebin/Pictures/markdown_assets/image-20200102152154116.png)]

  7. 任务模块 Task:包含异步任务和定时任务. 其中, 异步任务通常在业务逻辑中被触发并发往任务队列, 而定时任务由 Celery Beat 进程周期性地将任务发往任务队列.

  8. 消息中间件 Broker:代理Broker, 即为任务调度队列, 接收任务生产者发来的消息(即任务)更重要的智能是把海量的的消息缓冲住, 将任务存入队列。Celery 本身不提供队列服务, 官方推荐使用 RabbitMQ 和 Redis 等,或者干脆用云服务的消息队列服务:SQS

  9. 任务执行单元 Worker:Worker 是执行任务的处理单元, 它实时监控消息队列, 获取队列中调度的任务, 并执行它.

  10. 任务结果存储 Backend:Backend 用于存储任务的执行结果, 以供查询. 同消息中间件一样, 存储也可使用 RabbitMQ, Redis 和 MongoDB 等.

  11. 消息队列:

  12. MQ:Message Queue,(与服务器、存储、缓存、数据库同等重要,是现代互联网后台架构的基础组件)

  13. 作用:
    1. 异步:把没必要同步执行的程序,用消息队列暂存,然后用其他程序去异步执行,做到跨机器分散任务
    2. 解耦:有依赖关系的应用之间,用消息队列解除耦合
      1. A 和 B 两个业务有强耦合
      2. A B
    3. 削峰:把互联网的高峰请求,先缓冲下来,然后再慢慢的逐个处理
      1. 秒杀、团购的场景,用这种方式降低峰值请求
    4. 限流:
      1. 1000,每进来一个人 -1,每离开一个人 +1,
      2. 减到 0 ,就告诉后来者:人满了。
  14. 常见的消息队列:

    1. Redis,最简单
    2. Kafka,最适合做日志处理,单机几十万并发(每秒钟的请求)
    3. RabbitMQ,符合 MQ 标准的消息队列(每秒钟几万)
    4. RocketMQ,符合 MQ 标准的消息队列(每秒钟十几万)
  15. 安装 注意win10不支持celery4.3!!!!!!!!!! 所以需要额外安装在这里插入图片描述

shell pip install celery[redis]

  1. 创建实例 ~~~python import os from celery import Celery

    from social import settings from worker import config

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "social.settings")

    celery_app = Celery('social') celery_app.config_from_object(config) celery_app.autodiscover_tasks()

  2. 常规配置

    ```python 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/1' result_serializer = 'pickle' result_cache_max = 10000 # 任务结果最大缓存数量

    worker_redirect_stdouts_level = 'INFO' ```

  3. 启动 Worker

Linux / mac下: celery worker -A worker --loglevel=info

win: celery worker -A worker --loglevel=info -P eventlet

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://wakemeupnow.cn/article/celery/