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

2019-09-04 00:07:32 +08:00
 miniyao
假如启了 2 个 worker,用户 A 第一次的 request 是走 worker1 的 django 实例,用户 A 第二次的 request 是走 worker2 的 django 实例。

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

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

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

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

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

否者,需要设计成服务端通知模式,这就需要 websocket

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/597697

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX