现在的位置: 首页 > 综合 > 正文

Django+Rabbitmq+Celery 框架学习

2018年02月21日 ⁄ 综合 ⁄ 共 2133字 ⁄ 字号 评论关闭

       OJ2.0中可能会遇到多用户并发提交代码的情况。如果每个用户的代码都要运行一段时间,甚至超时,那么我们怎么处理呢?一般的做法有两种:

       1.我们单任务串行,也就是说一次只处理一个用户提交的代码,其他用户的请求处于等待状态。不过如果每个任务都处理很久,然后同时并发的用户请求达到一定数量的时候,那么我们的服务器由于要存储大量的等待的任务而导致资源耗尽,甚至奔溃。比如,OJ1.0在运行的过程中就有很多次崩溃了,我们不得不重启服务器。其实这和所谓的DOS攻击的原理差不多,但是我们不能采取丢掉任务,或者限制请求的方法来解决。

       2.我们可以采取异步来处理任务,把用户的请求用一个队列来存储,然后使用很多个work进程来同时处理,这样就显然能加快处理速度,当然,后期我们也得做压力测试,测试存储请求队列在请求数量达到多大的情况下,由于work的任务队列处理不完而导致奔溃。

      下面就来介绍OJ2.0 Rabbit+Celery的框架:     

  •   django:web框架,其实只能算作配角了;
  •   RabbitMQ:消息队列系统,负责存储消息;
  •   celery:worker进程,同时提供在webapp中创建任务的功能。
    安装

    需要安装RabbitMQ、Celery和Django-celery

    Celery和Django-celery的安装直接pip install ,也可以先下载压缩包,然后解压安装。

    安装RabbitMQ:

    sudo pip install -n rabbitmq
    

    启动RabbitMQ:

    sudo rabbitmq-server -detached
    

     

    安装celery:

    sudo pip install -n celery

    也可以到 http://pypi.python.org/pypi/celery#downloads 下载celery并安装:

    tar xzvf celery-2.2.7.tar.gz
    cd celery-2.2.7
    python setup.py build
    sudo python setup.py install

    启动celery:

    python manage.py celeryd -l info

    安装django-celery:

    sudo pip install -n djcelery

    到 http://pypi.python.org/pypi/django-celery#downloads 下载 django-celery 并安装:

    tar xzvf django-celery-2.2.4.tar.gz
    cd django-celery-2.2.4
    python setup.py build
    sudo python setup.py install

    这个过程会安装依赖包 django-picklefield,如有需要请自行下载编译。

     

    建立测试应用程序:

    django-admin.py startproject celerytest
    cd celerytest
    django-admin.py startapp hello
    cd hello

    修改project中的settings.py,在INSTALLED_APPS中加入以下内容:

    INSTALLED_APPS = (
      ...
      'djcelery',          # 加入celery
      'hello',             # 测试应用程序
    }

    在project的settings.py末尾添加RabbitMQ的配置:

    import djcelery
    djcelery.setup_loader()
    
    BROKER_HOST = "localhost"
    BROKER_PORT = 5672
    BROKER_USER = "guest"
    BROKER_PASSWORD = "guest"
    BROKER_VHOST = "/"

     

    当然,还得配置数据库选项,因为djcelery要用到数据库的。配置好之后执行:

    python manage.py syncdb

    可以执行 python manage.py 看一下,会发现 djcelery 应用程序给 manage.py 添加了许多celery*开头的命令, 这些就是控制worker的命令了。

     

    接下来我们写个task。新建 hello/tasks.py,内容如下:

    from celery.decorators import task
    
    @task
    def add(x, y):
      return x + y
    

    修饰符 @task 将add函数变成了异步任务。在webapp中调用add并不会立即执行该函数,而是将函数名、 参数等打包成消息发送到消息队列中,再由worker执行实际的代码(return x + y)。

    在一个终端启动celery。

    在另一个终端测试:

    $ python manage.py shell
    >>> from hello.tasks import add
    >>> r = add.delay(3,5)     # 执行这一行就能在worker的日志中看到运行状况
    >>> r.wait()

    可以看到,add函数是在worker上运行的,实现了异步的效果。当然,队列的特性决定了任务并不是实时执行的,可能有延迟, 有时甚至还会丢失,因此,队列不适合执行关键任务。而那些执行结果无关痛痒、对实时性要求不高的任务, 就可以大胆地交给RabbitMQ去处理,将WebApp解放出来吧。

     下面介绍OJ2.0的配置:地址

  • 抱歉!评论已关闭.