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

如何将web套接字与django wsgi集成,django,websocket,wsgi,gevent,gunicorn,Django,Websocket,Wsgi,Gevent,Gunicorn,我们有一个非常复杂的Django应用程序,目前由 apache/mod_wsgi并部署在一个 AWS ELB负载平衡器。客户端应用程序与服务器交互 使用AJAX。它们还定期轮询服务器以检索通知 并更新其状态。我们希望删除轮询并替换 它使用web套接字“推送” 因为任意实例处理来自客户端的web套接字请求 并保留这些web套接字,因为我们希望将数据推送到 可能不在提供源的同一实例上的客户端 对于推送数据,我们需要一种将数据路由到适当位置的方法 实例,然后从该实例到相应的客户端web 插座 我们意识

我们有一个非常复杂的Django应用程序,目前由 apache/mod_wsgi并部署在一个 AWS ELB负载平衡器。客户端应用程序与服务器交互 使用AJAX。它们还定期轮询服务器以检索通知 并更新其状态。我们希望删除轮询并替换 它使用web套接字“推送”

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

我们意识到apache/mod_wsgi不能很好地使用web套接字和 计划用nginx/gunicorn替换这些组件,并使用 gevent websocket工人。但是,如果多个辅助进程之一 从客户端接收建立web套接字的请求,如果 工作进程的生命周期由主gunicorn控制 进程,不清楚其他工作人员是如何处理的,或者实际上是如何处理的 非gunicorn进程可以向这些web套接字发送数据

一个具体的例子是:发出HTTP请求的用户是 指向一个EC2实例(主机),所需的行为是 发送给另一个用户,该用户的web套接字已完全打开 不同的例子。人们可以很容易地设想一个系统,其中包含一条消息 可以向每个实例上运行的代理(例如rabbitmq)发送一条消息 包含通过web套接字发送到连接的客户端的数据 对那种情况。但是这些消息的处理程序如何访问 在gunicorn的工作进程中接收的web套接字? 高级python web套接字对象创建了gevent websocket和 无法对工人可用的数据进行酸洗(它们是实例 方法(不支持酸洗),因此无法轻松共享 由工作进程转换为某个长期运行的外部进程

事实上,这个问题的根源在于如何使用web套接字 它们由来自客户端的HTTP请求发起,并由WSGI处理 服务器(如gunicorn)中的处理程序可以由外部用户访问 过程?gunicorn工人处理, 用于处理HTTP请求的消息将产生长时间运行的消息 挂在web套接字上的线程,并支持处理来自 将消息发送到已安装的web套接字的其他进程 通过这些工作进程连接

有人能解释一下web套接字和基于WSGI的HTTP请求是如何实现的吗 处理程序可能在我描述的环境中相互作用

谢谢

gunicorn工作进程(用于处理HTTP请求)会产生长时间运行的线程来挂起web套接字,并支持处理来自其他进程的消息以将消息发送到通过这些工作进程连接的web套接字,这似乎是不对的

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

通常在这种情况下,写作与阅读是分开处理的

当前正在处理websocket连接的工作程序将等待相关消息从消息服务器下来,然后将其传递到websocket


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

我认为您正确地评估了mod_wsgi+websockets是一个令人讨厌的组合

您会发现所有wsgi工作人员都被web套接字占用,并且(大规模)增加工作人员池的大小可能会因为内存使用和上下文切换而阻塞服务器


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

如果由于处理了一个HTTP请求,服务器需要向websocket发送一个推送通知,说明另一个用户已连接到同一主机或不同主机上的另一个工作进程,则发送工作进程必须将消息排队(在某个地方,但可能是每个工作者订阅的AMQP服务器)和接收工作者(从目标客户机抓取websocket的人)必须从队列中读取消息并将其发送到web套接字。这似乎是一种合理的体系结构吗?我不习惯将工作进程用于“其他工作”而不是请求/响应处理,但你似乎在说他们没有理由不能。对吗?websocket不再做简单的请求/响应处理了,是吗?它现在是一个成熟的双工通道。如果你愿意,你可以将websocket连接交给单独的工作人员池。是的,你的建议似乎是否定的rmal arch.to me.:)之后,我们切换到一种模式,使用NGINX作为HTTP代理,并将其代理到gunicorn(django)或nodejs。nodejs应用程序处理我们的web套接字。我们可能很快会放弃gunicorn,尝试uWSGI,因为我们相信性能会更好。我们是否将websockets支持切换回python/django将取决于我们是否真的认为这样做有很多好处。Nodejs现在似乎可以很好地处理这些websocket连接。