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

求助,求推荐 celery 的轻量级替代方案

  •  
  •   chaleaoch · 2020-06-02 17:17:34 +08:00 · 6937 次点击
    这是一个创建于 1626 天前的主题,其中的信息可能已经有所发展或是发生改变。
    特别简单的一个需求.
    django view 里面非阻塞调用一个第三方的 api. 然后将返回值作为参数调用 callback.
    view 里面直接返回 response 调用成功(第三方 api 返回什么无所谓).

    类似于发送短信验证码一样的需求.

    用 celery 太重了.
    起个线程有问题吗?需要注意什么吗?
    36 条回复    2021-04-23 23:43:51 +08:00
    madpudding
        1
    madpudding  
       2020-06-02 17:26:19 +08:00
    huey ?
    swulling
        2
    swulling  
       2020-06-02 17:27:19 +08:00
    https://github.com/rq/rq

    这个就不错,另外代码写的也不错,可以学习下
    676529483
        3
    676529483  
       2020-06-02 18:03:30 +08:00   ❤️ 1
    django 3.0 有个 django_simple_task,用 uvicorn 启动就可以用了,正在用,效果还可以
    chi1st
        4
    chi1st  
       2020-06-02 18:21:10 +08:00
    直接新起一个线程处理第三方接口问题不大
    rogwan
        5
    rogwan  
       2020-06-02 18:22:48 +08:00 via iPhone
    thread
    tcpdump
        6
    tcpdump  
       2020-06-02 18:29:02 +08:00
    太重了是什么意思,装了硬盘变重了?
    labulaka521
        7
    labulaka521  
       2020-06-02 18:35:36 +08:00
    nq
    Latin
        8
    Latin  
       2020-06-02 18:43:00 +08:00
    rq huey
    qW7bo2FbzbC0
        9
    qW7bo2FbzbC0  
       2020-06-02 18:54:54 +08:00
    django-q
    jabari
        10
    jabari  
       2020-06-02 19:19:16 +08:00
    rq
    baocaixiong
        11
    baocaixiong  
       2020-06-02 20:39:12 +08:00
    @tcpdump 老哥你要 xswl
    SystemLight
        12
    SystemLight  
       2020-06-02 20:43:45 +08:00
    django 也很重啊,不如考虑下 tornado -_-
    6d6f33
        13
    6d6f33  
       2020-06-02 20:45:35 +08:00
    用 RQ 把,小、稳。
    celery,我技术太菜,用做定时任务,在腾讯云服务器跑一段时间一点也查不出原因的就挂了,得手动重启。RQ 就活得好好的。
    当然,celery 肯定配置都对,配了自动重启,反正查不出原因,只能怪自己太菜。
    mrchi
        14
    mrchi  
       2020-06-02 20:45:40 +08:00
    @SystemLight tornado 连 webserver 都带了,岂不是更重
    wd
        15
    wd  
       2020-06-02 21:22:25 +08:00 via iPhone
    不就自己起个 thread 跑么
    Philippa
        16
    Philippa  
       2020-06-02 21:28:49 +08:00 via iPhone
    我觉得你另外启动一个 project,worker,不需要 celery,用 http 和它通讯,通讯完它给你接口发送报告。以后谁都可以调它,不要这个功能直接干掉那个 worker 就好了,侵入性低,简单直接。
    nonduality
        17
    nonduality  
       2020-06-02 21:49:48 +08:00
    celery 占用内存确实很大,依赖的库很多,而且貌似会内存泄漏,起单一个 celery 进程可以超过 400M 内存。
    nonduality
        18
    nonduality  
       2020-06-02 21:53:29 +08:00
    Django 能用的还有 APScheduler 。

    既能做任务队列又能做定时 /循环执行的,差不多只有 celery 。
    ericls
        19
    ericls  
       2020-06-02 22:00:25 +08:00 via iPhone
    如果真的是那种无所谓的任务 我来自荐下我的 django_simple_task

    注意你最好调整一下并发限制。另外如果把 API 请求用 asyncio 写 overhead 会小一些
    ericls
        20
    ericls  
       2020-06-02 22:01:24 +08:00 via iPhone
    起个线程也可以 但是最好有个线程池
    ClericPy
        21
    ClericPy  
       2020-06-02 22:41:06 +08:00   ❤️ 1
    这种量级没什么必要走消息队列吧
    这就个位数的任务, 也不用非得启动 celery 那么重吧
    最最简单的, 生产者消费者模式:
    启动服务的时候丢一个多线程后台跑着消费 Python 自带的 queue, 然后 api 被调用的时候把相关参数传入 queue 里去, 又线程安全, 又避免高并发出问题(可以加个 sleep 避免触及第三方 api 的 rate limit)
    如果需要并发, 那这个 background 就可以换成 thread executor, api 被调用的时候无脑给 pool 里 Submit 一个函数+参数就可以异步启动了

    不过如果 Django 经常要重启, 这就没法持久化 Callback 的参数了, 确实该用 celery 或者消息队列...
    youngce
        22
    youngce  
       2020-06-02 22:49:00 +08:00
    我的 celery 安安静静的跑了有一整年了,暂时没有看出啥问题。。。动态修改周期性任务执行计划还是挺香的
    HuberyPang
        23
    HuberyPang  
       2020-06-02 22:51:35 +08:00
    @ericls 老哥,请教下。django view 中启动线程,怎么配置线程池啊。每一次请求 view,就是开启了一个线程(我这么说没错吧),那么当线程池用完了,这时在有访问 view,会阻塞吗
    aladdindingding
        24
    aladdindingding  
       2020-06-02 22:57:55 +08:00
    单独起一个线程就好了
    from concurrent.futures import ThreadPoolExecutor

    executor = ThreadPoolExecutor(5)

    executor.submit()立马就有返回的 不会阻塞
    HuberyPang
        25
    HuberyPang  
       2020-06-02 23:20:23 +08:00
    ![测试了下,不会阻塞,就是还不是很懂这里的原因]( https://pic.downk.cc/item/5ed66dc0c2a9a83be5fa40d6.jpg)
    tulongtou
        26
    tulongtou  
       2020-06-02 23:30:29 +08:00
    我这 celery + rabbitmq 跑了 5 年多了,从 python2 跑到 python3,一直很好用啊,没感觉有多重
    Ritter
        27
    Ritter  
       2020-06-03 00:02:02 +08:00
    rq
    iConnect
        28
    iConnect  
       2020-06-03 00:23:51 +08:00 via Android
    @tulongtou
    @youngce

    celery 这么稳吗?我用过感觉每隔几个星期就假死一次 celery+redis
    gjquoiai
        29
    gjquoiai  
       2020-06-03 00:44:24 +08:00 via iPhone
    dramatiq
    ericls
        30
    ericls  
       2020-06-03 00:59:25 +08:00
    @HuberyPang 在 wsgi/asgi 入口附近起线程池 在 view 里面使用线程池。

    django 的 view 没有在线程池里面,是在主线程的
    skywatcher
        31
    skywatcher  
       2020-06-03 01:43:22 +08:00
    需求简单,但是看你要不要满足高可用。比如任务失败是否重试,任务丢失能否接受(机器挂了,服务重启了)。项目不大能简单切换,可考虑用异步 io 框架,应该都不需要线程池,框架本身支持,比如 tornado, fastapi 。Django 的话启动 http server 时启动一个线程池,在 api 调用时使用线程池执行即可。再者如果任务比较多,线程池有压力,可以考虑额外启动几个消费进程与 http 服务进程共享 queue,用 queue 来分发任务,消费进程获取任务执行。如果你要考虑到任务的管理(失败重试、任务不丢失、任务状态),那就考虑 celery,mq 等中间件
    Trim21
        32
    Trim21  
       2020-06-03 01:55:24 +08:00 via Android
    @iConnect Redis 会假死,amqp 不会
    Ehco1996
        33
    Ehco1996  
       2020-06-03 06:44:53 +08:00
    @ClericPy 我猜需求是不想在开一个进程去异步的做任务。让所有的事情都通过 django 自己干
    jswh
        34
    jswh  
       2020-06-03 09:55:31 +08:00
    起个线程自己做一下好了,反正是 python,又不是 PHP
    ytymf
        35
    ytymf  
       2020-06-03 15:24:34 +08:00
    Huey,很小很稳。定时异步都支持。。。。
    macrosea
        36
    macrosea  
       2021-04-23 23:43:51 +08:00
    围观
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5232 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 03:47 · PVG 11:47 · LAX 19:47 · JFK 22:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.