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

gunicorn 多 worker 运行 django 实例,怎么保证 每一个 django 是进程安全的,不会出现脏数据?

  •  
  •   miniyao · 2019-09-04 00:07:32 +08:00 via Android · 2483 次点击
    这是一个创建于 1935 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假如启了 2 个 worker,用户 A 第一次的 request 是走 worker1 的 django 实例,用户 A 第二次的 request 是走 worker2 的 django 实例。

    按正常情况,应该是第一次的 request 先完成,但是某些 io 特殊情况导致第一次的 request 未及时完成,这个时候第二个 request 已经来了,问题是第二个 request 走的是 worker2,worker1 阻塞不了 worker2 啊,会导致注重数据操作顺序的时候,worker2 把 worker1 要处理的数据提前弄脏了。
    8 条回复    2019-09-06 10:31:34 +08:00
    heww
        1
    heww  
       2019-09-04 00:09:02 +08:00
    数据库事务隔离了解下~
    ManjusakaL
        2
    ManjusakaL  
       2019-09-04 00:12:34 +08:00
    这个时候为啥要交给 L4/L7 的框架来做?

    你同一个用户有着依赖关系,B 依赖于 A 的成功结束,那么你为啥要同时发送两个请求?

    这种情况正确的思路难道不是顺序请求,确保 A 请求结束之后再发起 B 请求啊?
    dcoder
        3
    dcoder  
       2019-09-04 02:19:54 +08:00
    Django request 会对应到数据库的 transaction. 是数据库帮你搞定的, 基本只有数据库才是 stateful 的.
    cz5424
        4
    cz5424  
       2019-09-04 08:07:47 +08:00 via iPhone
    1,2 楼已经说的很清楚了,不是 worker1 或 2 的问题,请求有先后的话,可以用这个方法,从请求 1 拿到凭证再发给 2
    cuojue4655807
        5
    cuojue4655807  
       2019-09-04 11:31:14 +08:00
    不能保证无状态的 api 考虑下加业务锁?
    qqxx520
        6
    qqxx520  
       2019-09-04 13:19:12 +08:00 via Android
    加锁,可以在 redis 里写一个 key,请求完成后销毁,其他进程的请求判断 key 是否存在,是就返回状态码,让客户端等会再试
    jesnridy
        7
    jesnridy  
       2019-09-04 13:50:50 +08:00
    基本就是数据库层面解决的,避免事务幻读就考虑在数据列加唯一键或者更改数据库隔离级别。
    lolizeppelin
        8
    lolizeppelin  
       2019-09-06 10:31:34 +08:00
    HTTP 的请求就不应该有阻塞
    HTTP 设计本身就是无状态的才会有 fast cgi 这样的形式,http 请求本身就不应该有需要长时间执行的调用

    你要实现 B 请求在 A 未完成的时候阻塞本身就是错误的思路,违背了 HTTP 协议的本意
    如果 B 需要依赖 A 完成,那么 B 请求发现 A 未完成的时候直接返回 A 未完成,而不是阻塞

    由客户端轮询 B 请求,直到成功执行

    否者,需要设计成服务端通知模式,这就需要 websocket
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2783 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 07:55 · PVG 15:55 · LAX 23:55 · JFK 02:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.