经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
Django如何防止定时任务并发浅析
来源:jb51  时间:2019/5/14 9:49:23  对本文有异议

前言

django提供了commands类,允许我们编写命令行脚本,并且可以通过python manage.py拉起。

了解commands

具体django commands如何使用,大家参考官方文档即可:https://docs.djangoproject.com/en/2.2/howto/custom-management-commands/

一个坑

使用时遇到一个坑:在commands运行中的异常并不会打印到屏幕上,它要求我们必须抛出CommandError类型的异常才能被打印到屏幕中,具体参考:https://docs.djangoproject.com/en/2.2/howto/custom-management-commands/#command-exceptions

文件锁防并发

我们通常利用Crontab拉起定时任务,那么就会面临一个常见问题,如何避免前一次没结束而后一次再次启动的问题。

通常都是用文件锁来搞定这个事情,我做了一个简单的装饰器来包装Commands的handle方法,定义一套元类或者类装饰器都可以达到同样的目的,这里就不炫技了。

  1. # -*- coding: utf-8 -*-
  2. import fcntl
  3. import os
  4. from apps.settings import CRON_LOCK_DIR
  5.  
  6.  
  7. # 尝试加锁
  8. def try_lock(name):
  9. def decorator(func):
  10. def wrap(*args, **kwargs):
  11. os.makedirs(CRON_LOCK_DIR, exist_ok=True)
  12. with open('{}/{}'.format(CRON_LOCK_DIR, name), 'w') as fd:
  13. try:
  14. fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) # 加锁
  15. func(*args, **kwargs)
  16. fcntl.lockf(fd, fcntl.LOCK_UN) # 解锁
  17. except: # 加锁异常跳过
  18. pass
  19. return wrap
  20. return decorator

其中CRON_LOCK_DIR是文件锁的父目录,下面放了若干锁文件。

对Commands的handle方法指定锁文件名即可:

  1. class Command(BaseCommand):
  2. @try_lock('check_order') # 指定锁文件的名字
  3. def handle(self, *args, **options):
  4. pass

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对w3xue的支持。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号