我有一个Django 2.0,Celery 4和Scrapy 1.5的设置,我在Django自定义命令中有一个Spider,我需要定期调用这个命令,我使用Celery来调用这些命令,它们涉及到抓取网页和将一些结果保存到数据库中。
获取数据.py
class Command(BaseCommand):
help = 'Crawl for new data'
def handle(self, *args, **options):
settings = Settings()
settings.setmodule(crawler_settings)
process = CrawlerProcess(settings=settings)
args = {some needed args}
process.crawl(DataLogSpider, kwargs=args)
process.start()
celery .py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')
app = Celery('config')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
任务.py
@task()
def collect_data_information():
call_command('get_data')
( Django )settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_BEAT_SCHEDULE = {
'task-get-logs': {
'task': 'core.tasks.collect_data_information',
'schedule': crontab(minute='*/15') # every 15 minutes
},
}
为了简单起见,我删除了一些导入并减少了代码。问题是,当我运行我的celery 任务时,我的spider只会执行第一次,第二次我会得到ReactorNotRestartable
错误。我知道问题来自Twisted reactor被多次重启,这是不可能的。我已经研究了这些问题1,2,3和许多其他涉及相同错误的问题,但它们都没有考虑到使用Django保存到数据库时的并发问题。
当我尝试应用他们的解决方案来解决我的问题时,我收到了一个django.db.utils.OperationalError: SSL error: decryption failed or bad record mac
。我也查过了,这是由打开数据库连接的多个进程引起的,这实际上是因为他们的解决方案而发生的。
所以我的问题归结为:Is there a way to run Celery+Scrapy+Django without having problems with the Twisted reactor being opened and finished multiple times?
1条答案
按热度按时间xmq68pz91#
我自己找到了一个解决方案。我必须添加以下内容到by celery设置文件:
这会告诉celepie以全新的状态启动每个任务,因此每个任务都将在新进程中启动,并且不会发生ReactorNotRestartable问题。