django-gearman-commands 0.6.1

  • 发布于: 18 October 2018
  • 编辑: 628财经

 

pip install django-gearman-commands

项目描述

django-gearman-commands 是Django管理命令和基类的集合,旨在简化Django的开发和提交Gearman job服务的相关过程。

 

关于Gearmanclient客户端:

需要完成的job,这是一个web应用。

server服务端:接收job并提交给workers处理。

worker作业端:询问是否有job,并处理job。worker可独立运行任务。

生产环境中,最好有两个worker来确保高可用。

为什么要使用 django-gearman-commands?

 

django-gearman-commands解决的主要问题是编写worker,为你的Django APP 使用。

django-gearman-commands 提供了什么?

为你的worker是提供基础的类

GearmanWorkerBaseCommand可以代替哪些低级的API

提交任务更简单

gearman_submit_job 命令 可以提交新的任务到gearmand,不用自己编写worker,也不用使用manage.py的提交命令。

开搞

安装

你肯定现有一个Django的应用,并希望安装Django-gearman-commands,这是一个标准的Django应用程序,但他不提供任何的models,views和urls,他只包含少数的类,自定义管理命令和测试

只有一个新的依赖项添加到你的应用程序中,python-gearman API:

$ pip install -e git+https://github.com/Yelp/python-gearman.git@2ed9d88941e31e3358a0b80787254d0c2cfaa78a#egg=gearman-dev

另外有一个可选的依赖项,用来输出更好看的服务端信息。

$ pip install prettytable==0.5

最后添加django-gearman-commands  到你的setting的INSTALL中

INSTALLED_APPS = (
       # ...installed apps...
       'django_gearman_commands',
)

以及gearman的服务端配置

GEARMAN_SERVERS = ['127.0.0.1:4730']

编写worker

django_gearman_commands.GearmanWorkerBaseCommand 是一个基类,跟常规的gearman worker一样,所以你还是要编写自定义的部分。

假设我们想编写一个worker来导入一些耗时长,复杂度搞的数据,先在你的Django app 的management/commands路径下创建gearman_worker_data_import.py。

# -*- coding: utf-8 -*-
import django_gearman_commands

class Command(django_gearman_commands.GearmanWorkerBaseCommand):
   """执行导入数据的工作"""

   @property
   def task_name(self):
       return 'data_import'

   def do_job(self, job_data):
       # 执行复杂的数据输入
       your_code_performing_job_logic()

就想你看到的,你需要做三件事:

  • 创建文件 ‘management/commands/gearman_worker_MY_TASK_NAME.py’ 

  • 创建 Command class inheriting from django_gearman_commands.GearmanWorkerBaseCommand 这个类

  • 修改 task_name 属性 and do_job() method(方法)

 task_name 是任务的唯一标识,通过发送task_name以及可选的参数来完成任务的提交。

do_job() 是在提交job时调用的方法,如果使用参数提交,则job_data 不为 None

运行worker

$ ./manage.py gearman_worker_data_import

worker将启动,并将自己注册到server中,等待job的提交。

提交jobs

$ ./manage.py gearman_submit_job data_import

Submitting job: data_import, job data: (empty).
Job submission done, result: <GearmanJobRequest task='data_import', unique='8e610a031cef8aaf50c30f451d77808d', priority=None, background=True, state='CREATED', timed_out=False>.

默认情况下,job都是在后台提交的,‘gearman_submit_job’不会等待job的完成,你可以使用--foreground 参数,更多信息请查看 ./manage.py gearman_submit_job –help,如果过程没有问题,你的your_code_performing_job _logic,将在后台运行。

从crontab提交任务的方法如下:

*/5 * * * * /path-to-your-virtualenv/bin/python /path-to-your-project/manage.py gearman_submit_job data_import

 自定义的提交方法如下:

from django.core.management import call_command

def some_view(request):
    # ....处理view的逻辑....
    # 提交job到队列
    call_command('gearman_submit_job', 'data_import')

 通过使用job提交包装器命令'gearman_submit_job',您现在可以使用相同的API从console,cron和您的应用程序提交作业。

任务命令空间

比如,同一个django项目会有多个实例,在这种情况下,你可以将GEARMAN_CLIENT_NAMESPACE添加到django的setting中,以唯一的项目表示提交任务:

GEARMAN_CLIENT_NAMESPACE = 'MyCustomer1'

Gearman 服务端信息

 

gearman_server_info输出Gearman服务器的当前状态。如果您安装了prettytable依赖项,那么输出如下所示:

$ ./manage.py gearman_server_info
+---------------------+------------------------+--------------------+
| Gearman Server Host | Gearman Server Version | Ping Response Time |
+---------------------+------------------------+--------------------+
|    127.0.0.1:4730   |        OK 1.1.3        | 0.0006051063537598 |
+---------------------+------------------------+--------------------+.

+---------------+---------------+--------------+-------------+
|   Task Name   | Total Workers | Running Jobs | Queued Jobs |
+---------------+---------------+--------------+-------------+
| data_unlock   |       1       |      0       |      0      |
| data_import   |       1       |      1       |      0      |
| cache_cleanup |       1       |      0       |      0      |
+---------------+---------------+--------------+-------------+.

+-----------+------------------+-----------+-----------------+
| Worker IP | Registered Tasks | Client ID | File Descriptor |
+-----------+------------------+-----------+-----------------+
| 127.0.0.1 |   data_unlock    |     -     |        35       |
| 127.0.0.1 |   data_import    |     -     |        36       |
| 127.0.0.1 |  cache_cleanup   |     -     |        37       |
+-----------+------------------+-----------+-----------------+

 

如果你有很多worker,你可以使用命令参数过滤输出(区分大小写):

$ ./manage.py gearman_server_info cleanup
+---------------------+------------------------+--------------------+
| Gearman Server Host | Gearman Server Version | Ping Response Time |
+---------------------+------------------------+--------------------+
|    127.0.0.1:4730   |        OK 1.1.3        | 0.0006871223449707 |
+---------------------+------------------------+--------------------+.

+---------------+---------------+--------------+-------------+
|   Task Name   | Total Workers | Running Jobs | Queued Jobs |
+---------------+---------------+--------------+-------------+
| cache_cleanup |       1       |      0       |      0      |
+---------------+---------------+--------------+-------------+.

+-----------+------------------+-----------+-----------------+
| Worker IP | Registered Tasks | Client ID | File Descriptor |
+-----------+------------------+-----------+-----------------+
| 127.0.0.1 |  cache_cleanup   |     -     |        37       |
+-----------+------------------+-----------+-----------------+

 

使用Supervisor进行实际生产部署

在生产环境中,你需要确认两件事

1、你的Gearman server 是在运行的

2、你的Worker是在运行的

Supervisor - http://supervisord.org/ 流程的保姆。它允许您启动,重新启动和监视正在运行的进程。

 

Supervisor + Gearman

假设您已安装了Supervison并了解了基础知识,您可以在/etc/supervisor/conf.d中创建“gearman.conf”,其中包含以下内容:

[program:gearman]
command=/home/gearman/gearmand/gearmand/gearmand -q libsqlite3 --libsqlite3-db=/home/gearman/gearmand-sqlite.db -L 127.0.0.1
numprocs=1
directory=/home/gearman
stdout_logfile=/var/log/gearman.log
autostart=true
autorestart=true
user=gearman

这将启动 在/home/gearman/earmand/gearmand/gearmand 中的 gearman服务,当然参数可以更改

Supervisor + Workers

你可以创建 single.conf 文件 给所有single应用相关的worker使用,这将创建一个‘group’进程,并且允许您在重新部署新代码时立即重新加载与某些应用程序相关的所有工作程序。

举例来说,把所有与‘myapp’::相关的worker创建一个 ‘myapp.conf’ 在 /etc/supervisor/conf.d中 :

[program:myapp_data_import]
command=/path-to-your-virtualenv/bin/python /path-to-your-project/manage.py gearman_worker_data_import
numprocs=1
directory=/home/myapp/
stdout_logfile=/var/log/myapp_data_import.log
autostart=true
autorestart=true
user=myapp

[program:myapp_send_invoices]
command=/path-to-your-virtualenv/bin/python /path-to-your-project/manage.py gearman_worker_send_invoices
numprocs=1
directory=/home/myapp/
stdout_logfile=/var/log/myapp_send_invoices.log
autostart=true
autorestart=true
user=myapp

[group:myapp]
programs=myapp_data_import, myapp_send_invoices

 

重新部署后,您可以重新启动所有worker ::

$ supervisorctl reread
$ supervisorctl update
$ supervisorctl restart myapp:*
我建议使用Fabric自动执行此操作 -  http://docs.fabfile.org/

测试

 

测试位于tests / __ init__.py文件中。在根目录中有一个包装器'runtests.py'来设置具有最小依赖性的Django环境并运行测试。关键是允许在开发过程中测试django-gearman-commands而不需要完整的Django应用程序:

$ python runtests.py
正如您可以从runtests.py中读到的那样,测试期望Gearman服务器在标准端口4730上的localhost上运行。