如何将web套接字与django wsgi集成

时间:2013-02-28 16:23:25

标签: django websocket wsgi gevent gunicorn

我们目前有一个非常复杂的Django应用程序 apache / mod_wsgi并部署在一个后面的多个AWS EC2实例上 AWS ELB负载均衡器。客户端应用程序与服务器交互 使用AJAX。他们还定期轮询服务器以检索通知 并更新他们的州。我们希望删除轮询和替换 它使用“推”,使用网络套接字。

因为任意实例处理来自客户端的Web套接字请求 并抓住这些网络套接字,因为我们希望将数据推送到 可能不在提供源的同一实例上的客户端 对于推送数据,我们需要一种方法将数据路由到适当的位置 实例,然后从该实例到适当的客户端Web 插座。

我们意识到apache / mod_wsgi与web套接字不兼容 计划用nginx / gunicorn替换这些组件并使用 gevent-websocket工人。但是,如果有几个工作进程之一 接收来自客户端的请求以建立Web套接字,如果是 工人进程的生命周期由主炮兵控制 过程中,不清楚其他工人是如何处理的,或者事实上 非gunicorn进程可以将数据发送到这些Web套接字。

具体案例是:发出HTTP请求的用户是 定向到一个EC2实例(主机),所需的行为是数据 要发送给完全打开Web套接字的其他用户 不同的实例。人们可以很容易地想象出一个消息系统 可以向每个实例上运行的代理(例如rabbitmq)发送消息 包含要通过Web套接字发送到连接的客户端的数据 那个例子。但是这些消息的处理程序如何访问 网络套接字,是在gunicorn的工作过程中收到的? 高级python Web套接字对象创建了gevent-websocket和 提供给工人的不能被腌制(他们是实例 不支持酸洗的方法),因此无法轻易共享 通过工作流程进行一些长期运行的外部流程。

事实上,这个问题的根源归结为网络套接字如何 它们由来自客户端的HTTP请求启动并由WSGI处理 服务器(如gunicorn)中的处理程序可由外部访问 流程?枪炮工人处理的似乎不是正确, 旨在处理HTTP请求的将产生长时间运行 线程挂起到Web套接字并支持处理来自的消息 将消息发送到已经存在的Web套接字的其他进程 通过这些工人流程附加。

任何人都可以解释Web套接字和基于WSGI的HTTP请求的方式 处理程序可能会在我描述的环境中相互影响吗?

感谢。

2 个答案:

答案 0 :(得分:1)

我认为你已经做出了正确的评估,即mod_wsgi + websockets是一个令人讨厌的组合。

你会发现你的所有wsgi工作者都被网络套接字所困扰,并且由于内存使用和上下文切换,尝试(大规模)增加工作池的大小可能会阻塞服务器。

如果你喜欢坚持同步wsgi工作者架构(与gevent,twisted,tornado等实现的被动方法相反),我建议将uWSGI作为应用服务器。最新版本可以旧方式处理某些URL(即您现有的django视图仍然可以像以前一样工作),并将其他URL路由到异步websocket处理程序。这对您来说可能是一个相对平稳的迁移路径。

答案 1 :(得分:0)

  

枪支工作进程(用于处理HTTP请求)会产生长时间运行的线程以挂起到Web套接字并支持处理来自其他进程的消息以将消息发送到已附加的Web套接字,这似乎是正确的通过这些工人流程。

为什么不呢?毕竟,这是一个长期运行的连接。一个长期运行的线程来处理这样的连接似乎......对我来说绝对自然。

通常在这些情况下,写作与阅读分开处理。

当前正在处理websocket连接的worker将等待相关消息从消息传递服务器下来,然后将其传递给websocket。

如果愿意,您还可以使用gevent的异步友好队列来处理代码内消息传递。