PYTHON 十月 07, 2019

第8节、celerys及中间件

文章字数 7.6k 阅读约需 7 mins. 阅读次数 1000000

一、celerys

作用:

用户发起请求 request的时候 需要等待response 但是在视图函数中 有些功能执行需要时间 可能出现用户需要等待很久才会返回响应 导致用户的体验很差 还会容易出现代码中的异常

网站想要隔断时间同步一次数据 但是http需要出发才能执行

(1) celery

  1. 任务 task

    本质就是一个python函数

  2. 队列 queue

    将要执行的任务存放在对列中

  3. 工人 worker

    负责执行队列中的任务

  4. broker

    负责调度 redis的缓存

(2) 解决的问题

  1. 可以将耗时的代码放在celery中执行
  2. celery定时执行

(3) 安装

  1. pip3 install celery
  2. pip3 install celery-with-redis
  3. pip3 install django-celery
  4. pip3 install redis-server

(4)在settings.py文件中的install_apps添加 djcelery

INSTALLED_APPS = [
    ...
    'App',
    'djcelery',
]

在底部添加如下代码

#djcelery
import djcelery
djcelery.setup_loader() #初始化
BROKER_URL = 'redis://127.0.0.1:6379/0' #链接redis 选择数据库0
#BROKER_URL = 'redis://:密码@127.0.0.1:6379/0'
CELERY_IMPORTS = ('App.task') #导入任务py文件 App是应用名称 task是任务文件名称

(5) 创建task任务文件 在App下

App/task.py

from celery import task
import time
#要执行的任务
@task
def test():
    print('today is a good day1')
    time.sleep(5)
    print('today is a good day2')

(6) 执行迁移

python3 manage.py migrate

(7) 在project下创建celery.py文件

from __future__ import absolute_import

import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings')

app = Celery('portal')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

(8) 在project/init.py文件添加如下代码

from .celery import app as celery_app

(9) 在视图函数中 调用费时的任务

from App.task import test

def index(req):
    test.delay() #把活添加到队列 不会阻塞
    return HttpResponse('首页')

(10) 启动redis

redis-server

redis-cli

(11) 启动服务

python3 manage.py runserver

(12) 启动worker

在打开一个终端

cd /django的工作目录

python3 manage.py celery worker –loglevel=info

(13)定时执行

在settings.py文件中添加如下代码

  • 定时执行一个任务

from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    'schedule-test1':{
        'task':'App.task.test', #定时执行的任务
        'schedule':timedelta(seconds=7), #执行间隔
    }
}
  • 定时执行多个任务


from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    'schedule-test1':{
        'task':'App.task.test',
        'schedule':timedelta(seconds=7),
    },
    'schedule-test2':{
        'task':'App.task.test2',
        'schedule':timedelta(seconds=2),
        'args':['xlg']
    }
}
  • 在task添加如下任务

from celery import task
import time
#要执行的任务
@task
def test():
    print('today is a good day1')
    time.sleep(5)
    print('today is a good day2')

#定时任务2
@task
def test2(arg):
    print('{} is a very shuai'.format(arg))

启动顺序

  1. python3 manage.py runserver
  2. python3 manage.py celery worker –loglevel=info #开启异步执行调度
  3. python3 manage.py celery beat –loglevel=info #开启定时任务

二、中间件

作用:
在请求与响应之间 进行某些操作的过滤

  1. IP限制

    新建一个表 限制IP访问的

  2. 限制url请求

    比如:没登录访问需要登录的路由地址 可以重定向到登录视图

  3. 缓存处理

    访问的时候判断访问的视图函数是否有缓存 如果有 则直接响应缓存

中间件本质就是一个python类

方法:

  1. process_request(self,request) 在执行视图之前被调用 每次请求都调用 url路由地址分发之前 返回None 或者 HttpResponse
  2. process_view(self,request,view_func,view_args) 视图函数调用之前 返回None 或者 HttpResponse
  3. process_template_response(self,equest,response) 视图中执行完调用 每个请求都很会调用 返回None或者 HttpResponse
  4. process_response(self,request,response) 响应返回浏览器之前调用 每个请求都会调用 返回HttpResponse对象
  5. process_exception(self,equest,exception) 当视图抛出异常时 调用 返回HttpResponse 对象

实例:

目录结构

project/
    App/
    project/
    manage.py
    middleware/
        App/
            myMiddle.py

myMiddle.py添加如下代码

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect

class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print(request.path)
        print(request.method)
        print(request.META['REMOTE_ADDR'])
        # if request.META['REMOTE_ADDR'] == '127.0.0.1':
            # if IPModel.objects.filter(ip=request.META['REMOTE_ADDR']).first():
            # return HttpResponse('就不让你访问!')


    def process_exception(self,equest,exception):
        print(exception)
        return redirect('/')

视图函数

from django.shortcuts import render,HttpResponse
import time,random
# Create your views here.

from App.task import test

def index(req):
    # test.delay() #把活添加到队列 不会阻塞
    return HttpResponse('首页')


def error(req):
    val = random.randint(0,4)
    print(8/val)
    return HttpResponse("算个数")

添加到settings.py的middle中

MIDDLEWARE = [
    'middleware.App.myMiddle.MyMiddle',
]

上一篇:
下一篇:
0%