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

请问 django 的 models 的 singal 是否会不够稳定而导致遗漏?

  •  
  •   huisezhiyin · 2017-05-29 04:35:04 +08:00 · 2106 次点击
    这是一个创建于 2496 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我在项目中使用了 receiver 来监测 django models(mysql)的 post_save 信号, 这个 receiver 发送一个异步任务至 celery,异步任务写入数据至 redis,最后由一个脚本取出数据来进行统计任务。

    receiver 的写法如下:

    @receiver(post_save, sender=test_models)
    def record_processor(sender, instance, **kwargs):
    tasks.test_task.apply_async(args=[instance.id])

    异步任务(celery)如下:

    @app.task(bind=True)
    def record_test(self, test_models_id):
    try:
    test = test_models.objects.get(id=test_models_id)
    except:
    return
    date = datetime.now().date()
    key2 = "{0}:{1}".format(date, "test_num")
    pipe = r.pipeline()
    pipe.incr(key2)
    pipe.expire(key2, expired_time)
    pipe.execute()


    但在整个项目工作过程中,只有约十分之一的数据发送到了 redis 中——异步任务没有报错提醒。我不确定是哪个环节出了问题(从经验来看似乎 django 中 sql 的 singal 发送会有些不够稳定),想询问一下可能的原因以及解决的方案
    6 条回复    2017-05-31 21:22:48 +08:00
    shellfly
        1
    shellfly  
       2017-05-29 09:25:14 +08:00
    猜想大概有几种可能,可以逐一排除一下:
    1. update 不发送 post_save 的 signal。代码里有的地方是直接 update 而不是调用的 save
    2. save 放在了一个 transaction 里面。task 的代码是发送到 celery 上执行的,可能这时候 transaction 还没提交,objects.get 会报错,被你 catch,return 掉了
    3. redis 里的 key 被其他地方重复使用。这个搜一下代码就知道了
    4. 统计脚本有问题
    Danfi
        2
    Danfi  
       2017-05-29 10:55:56 +08:00
    估计是数据还没保存到数据库任务就已经运行了 test_models.objects.get(id=test_models_id) ,然后获取不到数据
    111111111111
        3
    111111111111  
       2017-05-29 19:42:37 +08:00 via Android   ❤️ 1
    receiver 和 task 里打个 log 看看
    另外数据库是读写分离的么
    huisezhiyin
        4
    huisezhiyin  
    OP
       2017-05-31 10:15:11 +08:00
    已解决
    因为使用了读写分离的缘故 导致这个信号的异步任务发起时没有从读库获取对应的信息 现在在异步任务里加一个 delay 应该就可以解决了
    huisezhiyin
        5
    huisezhiyin  
    OP
       2017-05-31 10:15:30 +08:00
    @111111111111 是的 应该是读写分离的缘故 读库速度较慢
    wingyiu
        6
    wingyiu  
       2017-05-31 21:22:48 +08:00
    更好的办法是用 canal 吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4755 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 09:46 · PVG 17:46 · LAX 02:46 · JFK 05:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.