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
kaiccc
V2EX  ›  Python

Django 启动时如何启动一个新线程

  •  
  •   kaiccc · 2019-04-18 11:15:41 +08:00 · 7086 次点击
    这是一个创建于 2047 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求:Django 在启动时初始化一个子线程,用于在后台轮训心跳任务

    心跳任务,监控其他节点

    目前测试情况:

    1.定时器( apscheduler )的方案,并不是我想要的。比如 任务可能随着节点增多,本来 5 秒能处理完的 job,变成 10 秒。apscheduler 做不到顺延执行同 job (我是没找到办法)

    2.尝试过 在 view 中创建线程,加载的代码没问题,但是创建线程无效果没 log。猜测 manage.py runserver 的时候是 fork 了子进程。

    1. manage.py 中创建线程,会阻塞主进程。

    那位大佬 来指点一下。小弟感谢不尽(抱拳)

    18 条回复    2019-06-12 16:51:36 +08:00
    wnh3yang
        1
    wnh3yang  
       2019-04-18 11:50:03 +08:00
    用芹菜队列应该可以
    keepeye
        2
    keepeye  
       2019-04-18 11:55:32 +08:00
    创建线程怎么会阻塞主线程呢?能贴下代码么?

    我用 tornado 也可以创建线程啊

    ```
    # 创建队列处理线程
    threading.Thread(target=handle_queue, name="handle_queue").start()
    # 启动 tornado
    port = os.environ.get('PORT', 8888)
    api.listen(port)
    print('listen on {}'.format(port))
    tornado.ioloop.IOLoop.current().start()
    ```
    phithon
        3
    phithon  
       2019-04-18 11:56:29 +08:00
    创建线程的操作在哪都不会阻塞主线程吧,是不是你 join 了。。
    wizardoz
        4
    wizardoz  
       2019-04-18 12:00:44 +08:00
    好多业务通过 celery 就能做到,但是你问的是如何开线程,把创建线程的代码放在 app 的 __init__.py 中即可,并保证 app 会被 import
    neoblackcap
        5
    neoblackcap  
       2019-04-18 12:01:22 +08:00
    开两个服务,Python 里面就不要用什么线程,当线程死了就好了。
    还有就是正常一点都不会搞什么 view 中启动线程做心跳检测,你的检查周期跟请求的生命周期绑定?这个设计我只能投反对票。
    还有就是生产环境不会用 manage.py runserver,那个只是给你开发用的。
    如果你生产环境用 uwsgi,那么它已经自带心跳检查了,不知道你的心跳想怎么做,一般 http 的它还是能做的,你可以看看 uwsgi 的文档
    wizardoz
        6
    wizardoz  
       2019-04-18 12:03:15 +08:00
    manage.py 中创建线程不科学,manage.py 这个文件只是调试的时候用的,真正部署以后这个文件不会执行。
    myyou
        7
    myyou  
       2019-04-18 12:07:22 +08:00
    "apscheduler 做不到顺延执行同 job"是什么意思?” misfire_grace_time “参数是你要的吗?
    JamesMackerel
        8
    JamesMackerel  
       2019-04-18 12:48:24 +08:00 via iPhone
    Django crontab
    guyujiezi
        9
    guyujiezi  
       2019-04-18 12:53:39 +08:00
    首先,你这个解决方案并不恰当,用 supervisor 启动独立守护进程更加合适,不过你的方案要实现也并非不可能。

    django 程序一般会被托管给 WSGI 容器来运行,你在 django 程序中无法预料会是以多进程或是多线程运行,你需要一个全局互斥对象( Mutex )来保证这个线程只被运行一次,可以通过文件锁来实现
    kaiccc
        10
    kaiccc  
    OP
       2019-04-18 13:54:45 +08:00
    可能说的比较乱。
    我只是想 创建 django 启动时加载一个子线程
    kaiccc
        11
    kaiccc  
    OP
       2019-04-18 13:57:33 +08:00
    @wizardoz 试过加载 init 中,通过 manage.py 启动项目 会阻塞 启动。(子线程创建没问题,但是子线程里是死循环,来处理业务)
    est
        12
    est  
       2019-04-18 14:02:58 +08:00
    wsgi 架构里 线程是 anti pattern。建议放弃治疗。
    Qzier
        13
    Qzier  
       2019-04-18 14:19:13 +08:00
    首先你要使用 BackgroundScheduler,然后在你 app 下的 apps.py 中的 AppConfig 子类添加 ready 方法,该方法每次应用载入前被启动一次,然后在 INSTALLED_APPS 注册该类名,而不是 app 名。
    kaiccc
        14
    kaiccc  
    OP
       2019-04-18 14:53:59 +08:00
    @Qzier 我只是想 创建 django 启动时加载一个子线程 ,不需要 apscheduler
    kaiccc
        15
    kaiccc  
    OP
       2019-04-18 14:55:11 +08:00
    @myyou 触发器每 5 秒执行,但是任务 实际耗时 10 秒。顺延执行,上个耗时 10 秒任务完成后的 5 秒 触发
    Aprilming
        16
    Aprilming  
       2019-04-18 15:27:40 +08:00
    django.channles,可以试试,有延时其中任务这个功能,你可以创建一个 5 秒的延时任务,但时间之后,执行任务 ,执行完毕,在去掉创建延时任务的接口。
    hakono
        17
    hakono  
       2019-04-20 20:53:09 +08:00
    如果只是单纯想要启动时创建个进程的话,直接在对应的 app 的 apps.py 里创建不就好了

    apps.py 的对应 AppConfig 类里的 ready()方法会自动被调用,在 ready()方法里创建进程就行了

    不过有点要注意的是,python manage.py runserver 会启动两个 django 进程,另一个进程是用来监视代码变更动态重启服务的,这个进程也会调用 ready()方法。这里需要自己处理选择检测下,别多次创建进程
    gollum9526
        18
    gollum9526  
       2019-06-12 16:51:36 +08:00
    django 创建子线程确实会阻塞的,应该是 python 全局锁
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2646 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 05:57 · PVG 13:57 · LAX 21:57 · JFK 00:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.