在进行定时获取代理ip, 黑名单ip,以及进行ip校验,相关信息及特征获取时,需要用到定时任务,常见的使用 linux 的crontab 来实现定时任务。但是为了在使用django,保持设计的一致性,就采用 celery 消息队列的定时任务来做。
开发环境:
centos 7
python3.5
Name: celery Version: 4.0.2
mongodb, django d都是最新的
有关celery
[直接摘自参考的博客,懒得写]
Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务( async task )和定时任务( crontab )。它的架构组成如下图:
可以看到, Celery 主要包含以下几个模块:
任务模块
包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。
消息中间件 Broker
Broker ,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。 Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。
任务执行单元 Worker
Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。
任务结果存储 Backend
Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。
异步任务
使用 Celery 实现异步任务主要包含三个步骤:
创建一个 Celery 实例
启动 Celery Worker
应用程序调用异步任务
以下是自己写的一个定时任务,整体结构没问题。并能很好的运行。
文件结构如下:
files structure:
celery_task
|- __init__.py
|- celeryconfig.py
|-obtain_data_task.py
|-obtain_model_task.py
从以上结构可以看出, celery_task 被配置为python的一个module
1, init.py
# coding:utf-8
from __future__ import absolute_import
from celery import Celery
app = Celery("service")
app.config_from_object("celery_task.celeryconfig")
2, celeryconfig.py
from __future__ import absolute_import
from datetime import timedelta
from celery.schedules import crontab
BROKER_URL = "mongodb://10.168.99.118:27017/celery_service"
# CELERY_RESULT_BACKEND = "mongodb://10.168.99.118:27017/celery/result"
# CELERY_RESULT_BACKEND = 'mongodb://10.168.99.118:27017/'
# CELERY_MONGODB_BACKEND_SETTINGS = {
# 'database': 'test',
# 'taskmeta_collection': 'result',
# }
CELERY_TIMEZONE = "Asia/Shanghai"
CELERY_IMPORTS = (
"celery_task.obtain_data_task",
"celery_task.obtain_model_task"
)
CELERYBEAT_SCHEDULE = {
"get_proxy_20_min": {
"task": "celery_task.obtain_data_task.get_proxy",
"schedule": timedelta(minutes=20),
# "schedule": crontab(minute="*/20"),
"args": ()
},
"check_proxy_10_min": {
"task": "celery_task.obtain_data_task.check_proxy",
"schedule": timedelta(minutes=11),
# "schedule": crontab(minute="*/11"),
"args": ()
},
"get_rbl_20_min": {
"task": "celery_task.obtain_data_task.get_rbl",
"schedule": timedelta(minutes=20),
# "schedule": crontab(minute="*/20"),
"args": ()
},
"generate_train_set_4_day": {
"task": "celery_task.obtain_model_task.generate_train_set",
"schedule": timedelta(hours=96),
# "schedule": crontab(day_of_month="2-29/4"),
"args": ()
},
"generate_model_day": {
"task": "celery_task.obtain_model_task.generate_model",
"schedule": timedelta(hours=100),
# "schedule": crontab(day_of_month="2-29/5"),
"args": ()
},
}
3, obtain_data_task.py
from __future__ import absolute_import
from celery_task import app
import os
import sys
cwd = os.path.dirname(__file__)
package_path = os.path.join(cwd, "../")
sys.path.append(package_path)
import api_extract
import ip181
import check_proxy
import raw_black_ip
import train_data
@app.task
def get_proxy():
"""
get the raw proxy data
then check proxy, obbtain the real useful proxy
get the proxy items
:return:
"""
ae = api_extract.ApiExtraction()
ae.extract()
ei = ip181.ExtractIp()
ei.extract_page()
@app.task
def check_proxy():
"""
check proxy run in a single process
:return:
"""
# cp = check_proxy.CheckProxy()
# cp.run()
td = train_data.TrainData()
td.get_proxy_items()
@app.task
def get_rbl():
rbi = raw_black_ip.RawBlackIp()
rbi.run()
td = train_data.TrainData()
td.get_rbl_items()
# normal ips process in a single process
4, obtain_model_task.py
from __future__ import absolute_import
import time
from celery_task import app
import os
import sys
cwd = os.path.dirname(__file__)
package_path = os.path.join(cwd, "../")
sys.path.append(package_path)
import train_data
import train_set
import random_forest
@app.task
def generate_train_set():
"""
4 days
:return:
"""
ts = train_set.TrainSet()
ts.generate_train_set()
@app.task
def generate_model():
"""
5 days
:return:
"""
random_forest.train_rf()
5, execution
open shell in the direction out of celery_task, and input follow command , then press ENTER
$ celery -A celery_task worker --loglevel=info -B
reference docs
异步任务神器 Celery 简明笔记
https://fast.v2ex.com/t/327228