哎, socket.io 对于 python 容器 多 worker 模式 来说好像是个死局

2016-07-22 12:32:57 +08:00
 awanabe
不管是 gunicorn 或者 uwsgi , 只要开启了多 worker , 就是多进程。
socket.io polling 的时候就会大部分的找不到对应 connection 。

所以官方推荐用 gunicorn 的原因是,用单 worker 可以发挥 协程 的最大作用。

而 uwsgi 因为对协程支持不好,转而用 多 worker 突破 python 全局锁提高并发的方式, 对于 socket.io 来说就是死局。
6499 次点击
所在节点    Python
34 条回复
playniuniu
2016-07-22 12:49:28 +08:00
试试这个

https://github.com/miguelgrinberg/python-socketio

用 gevent ,貌似还可以
2225377fjs
2016-07-22 12:55:53 +08:00
单 worker 多 worker 跟协程其实并没有太大关联啊,为啥多 worker 就不能最大发挥协程作用了。。。。
其实脱离 uwsgi , gunicorn 这些环境,单纯 python 也能够很好的解决楼主这问题。
(感觉现在 python 的生产环境大家都被一些东西困住了,就类似于总是用人提到 Java 就是 Spring , Tomcat 啥的)
awanabe
2016-07-22 13:24:00 +08:00
@playniuniu gevent eventlet 都是协程 gunicorn 都支持,只是没发用多 worker 模式
awanabe
2016-07-22 13:26:22 +08:00
@2225377fjs 主要问题是 多 worker 多进程导致 socketio 没法找到对应的 connection

你说的不在点上。 我说的主要是为了解决 python GIL 问题而出现的多进程模式存在的问题
BOYPT
2016-07-22 13:28:08 +08:00
这类情况一般是需要用一个 redis 之类的来共享 session ,不过 socketio 的 socket 的实现可能要改了
awanabe
2016-07-22 13:34:18 +08:00
@BOYPT 这个共享 session 也没办法吧, 每次请求都是 送到容器的 master 进程, 然后 master 去随机去负载均衡, 去分配其中一个 worker ,分配的 worker 不是之前那个的话,这样长连接就断了。。
BOYPT
2016-07-22 13:35:04 +08:00
看了下模块, Feature 里面不就已经有多服务支持了吗,正是用 redis 做消息共享的
https://pypi.python.org/pypi/python-socketio

Optional support for multiple servers, connected through a messaging queue such as Redis or RabbitMQ.
BOYPT
2016-07-22 13:37:43 +08:00
@awanabe 长链接只要建立就不可能一直切换了吧,一直换 worker 那还能叫长链接咩
至于断开重连,那对 socket.io 来说已经是另外一个 session ,但是对业务上还是同一个 session ,要你代码处理好业务逻辑
aisk
2016-07-22 13:38:55 +08:00
反正你迟早要到多节点上部署的,不找个第三方的东西来共享 session 怎么都是死局。
glasslion
2016-07-22 14:12:50 +08:00
@awanabe " 每次请求都是 送到容器的 master 进程, 然后 master 去随机去负载均衡, 去分配其中一个 worker"

这个推论是不正确的。
参考 今年 Pycon 上 Django Channels 的演讲 https://speakerdeck.com/pycon2016/andrew-godwin-reinventing-django-for-the-real-time-web , 负载均衡不是随机的,用一致性哈希去解决
glasslion
2016-07-22 14:17:21 +08:00
@awanabe 当然用来做 websocket 通信的这个组件确实不能用 gunicorn 或 uwsgi 来跑。 WSGI 本来就不支持持久化连接和服务端推送
awanabe
2016-07-22 14:17:38 +08:00
@glasslion 涨姿势
awanabe
2016-07-22 14:19:04 +08:00
@glasslion 那是否可以独立一个 app ,比如用 tornado 单独做一个只做 websocket 的应用, 单独服务?
rrfeng
2016-07-22 14:24:46 +08:00
大概和你们讨论的重点没什么关系

但是容器里为啥还要开多个进程?难道不应该是单容器单进程……

之前看过 docker 和 systemd 之争的文章,本来觉得有点奇怪,但是看到这个问题忽然间理解了一点。
2225377fjs
2016-07-22 14:25:31 +08:00
@awanabe 我的意思是你可以考虑脱离 uwsgi 这些环境,直接 python 就可以有很好的解决方案。
clino
2016-07-22 14:28:22 +08:00
"uwsgi 因为对协程支持不好" 哪里支持不好啊? 详细说下?
glasslion
2016-07-22 14:41:35 +08:00
@awanabe 可以。同理还可以用第三方的服务推送服务
awanabe
2016-07-22 14:43:26 +08:00
awanabe
2016-07-22 14:44:51 +08:00
@rrfeng python 的 GIL 导致 单进程多线程 效率很低, 只能换用多进程换取效率
awanabe
2016-07-22 14:45:54 +08:00
@glasslion 单独的服务 对应的麻烦点就是 用户识别

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

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

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

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

© 2021 V2EX