任务调度系统
项目背景
通常管理定时任务,会基于linux的crontab进行。使用crontab定时任务的好处是简单,系统自带服务,只需简单配置即可运行。 但是,随着任务的数量越来越多,基于crontab的定时任务功能,逐渐暴露出了一些弊端:
1.配置麻烦,业务应用每增加一条定时任务,都需要OP操作服务器
2.管理不便,任务数量繁多,要启动、修改、删除定时任务等很不方便
3.不清任务是否已经执行成功,执行日志不便管理
4.在多台服务器上,配置不同的定时任务,很难进行集中管理
5.基于crontab的定时任务,只能精确到分钟级别,更细粒度的定时功能无法完成
目标
建设一套任务调度系统,主要实现以下功能
一.实现统一的后台管理
在web后台可实现任务的增、删、改、查
二.定时功能
1.提供类crontab定时管理
2.实现秒级/毫秒级定时功能
3.任务执行日志查看
三.异步任务(消息队列)
基于消息队列,实现主动投递任务,将应用端一些耗时的操作,加入消息队列,实现快速响应请求,后端异步处理任务的功能
典型场景:
1.群发邮件/短信
2.app消息推送等 ...
技术栈
Python3.6
celery
django
环境需求
alpine3.6[gcc,linux-headers,musl-dev]
uwsgi
python3.6
celery4.0.2
Django==2.0.1
python包:redis auth msgpack librabbitmq django-celery sqlalchemy django-celery-results flower django-celery-beat
线上部署
一.Nginx配置
server {
listen 80;
server_name localhost;
location / {
include uwsgi_params;
#uwsgi_pass 192.168.110.128:6000;
uwsgi_pass celery:6000;
uwsgi_param UWSGI_SCRIPT task.wsgi;
uwsgi_param UWSGI_CHDIR /home/www;
index index.html index.htm;
client_max_body_size 35m;
}
location /static {
alias /home/www/task/static;
}
#celery flower prefix url
location /productor/ {
rewrite ^/productor/(.*)$ /$1 break;
proxy_pass http://172.17.219.224:5555;
proxy_set_header Host $host;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
auth_basic "Restricted";
#auth_basic_user_file conf/authpasswd;
auth_basic_user_file /usr/local/nginx/conf/authpasswd;
}
}
二.python服务配置
# 部署静态资源
python manage.py collectstatic
#数据库
python manage.py migrate
#启动uwsgi服务
uwsgi --ini /etc/uwsgi.ini
#启动celery守护进程
celery worker -l info -A task
#启动beat,定时任务进程
celery beat -l info -A task --scheduler djcelery.schedulers:DatabaseScheduler
#启动flower,用于主动投递任务
celery flower -l info -f /tmp/celery_flower.log --address=0.0.0.0 --port=5555 -A task --url_prefix=productor
#创建root帐号
python manage.py createsuperuser
如何使用?
1.定时任务功能
登录后台管理即可
http://localhost/admin/
2.主动投递任务,消息队列功能
curl -u root:testxxx -i -X POST -H "'Content-type':'application/json'" -d '{"args" :["www.test.com"]}' http://task.web.com/productor/api/task/send-task/remote.tasks.http