V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
wuwukai007
V2EX  ›  Python

Linux django 中使用 apscheduler 定时任务 数据库连接丢失问题

  •  
  •   wuwukai007 · 2019-12-27 17:53:43 +08:00 · 4612 次点击
    这是一个创建于 1818 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 之前项目在 windows 中部署,用的 apscheduler 做定时,初始化是放在 urls.py 中导入定时任务,任务中用到了 django 的 orm,不会出现数据库连接丢失情况
    • 现在项目迁移到了 linux,使用 supervisor + gunicorn + django,因为定时任务初始化有用到 django,所以不能放在 urls.py 中导入定时任务,放到了 wsgi.py 中末行导入,定时任务第二天执行时会出现 django 的 ORM 数据库连接丢失,我在定时任务启动前用了 close_old_connections()方法手动刷新连接,可以解决。
    问题:windows 中定时任务是在加载 wsgi.py 之前 导入的,linux 中是在 wsgi.py 加载之后导入的,但是理论上定时任务都是在 django 的会话中的,不应该会存在数据库丢失情况啊!
    
    7 条回复    2019-12-29 18:03:04 +08:00
    fhy1994
        1
    fhy1994  
       2019-12-27 18:07:53 +08:00
    我是 docker 跑的 flask 单独起了一个容器跑 apscheduler
    之前也遇到数据库丢失连接 因为我的定时任务是每天跑一次
    代码加入 mysql Pre-ping 无效

    后来写了个每 20 分钟去查下数据的定时任务
    解决了 `MySQL server has gone away` 的问题
    fhy1994
        2
    fhy1994  
       2019-12-27 18:15:33 +08:00
    顺便问大家伙个问题 docker 跑的 apscheduler
    每执行一次任务内存使用就会增加 容器内存占用会越来越大
    用的 BlockingScheduler 模式
    celery 也发现这问题
    任务调用 gc.collect() 无效
    est
        3
    est  
       2019-12-27 18:16:22 +08:00
    如果不理解 WSGI 各个对象的生存周期,尽量不要乱塞东西到 urls.py 或者 wsgi.py 的全局变量里去。
    wuwukai007
        4
    wuwukai007  
    OP
       2019-12-27 18:16:42 +08:00 via Android
    @fhy1994 django 的数据库连接 django 本身会维护,只是不知道是不是放在了 wsgi.py 的末行,django.setup 执行之后会导致没加载到 django 环境中?但是第一天执行了好奇怪。
    youngce
        5
    youngce  
       2019-12-27 18:22:58 +08:00
    @wuwukai007 #4 你的理解大概没有问题,你的数据库操作时间间隔太长,数据库已经抛弃了这个链接。django 在处理 request 时,会检查数据库连接是否存活,你大概是在脚本里调用了 django orm,所以没有这个操作。大概的解决办法,一种时你自己在调用 orm 时,实现 django 的数据库连接检查。另外一种就是,换 SQLAlchemy
    wangyongbo
        6
    wangyongbo  
       2019-12-27 18:33:19 +08:00
    我用的 mysql, mysql 有个 wait_timeout, 一个连接 超过这个时间没有操作, 就被断开了。
    所以我加了一个 异常捕获, 重新连接的代码, 也可以解决这个问题。
    断开之后,重连
    from django.db import connection
    connection.connect()
    meiyoumingzi6
        7
    meiyoumingzi6  
       2019-12-29 18:03:04 +08:00
    升级 apscheduler 版本
    可以去翻下 github 在某个版本修改了这个问题,
    是没有及时删除旧连接导致的

    明天上班给你看下是在哪个版本修复的(我们之前排查过这个问题…最后发现官方修了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:00 · PVG 22:00 · LAX 06:00 · JFK 09:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.