【问题标题】:Is multiplexing websocket connections an important optimization in Django Channels >= 2?多路复用 websocket 连接是 Django Channels >= 2 中的重要优化吗?
【发布时间】:2021-07-11 14:15:39
【问题描述】:

我维护了一个 Django Channels v1 应用程序,其中六个消费者通过一个 WebSocket 连接多路复用。我正在升级到 Django Channels v2,不再支持连接(解)多路复用;见GitHub Issue #825 - (Re)Implement Multiplexing。如果我想复用,我可以使用channels-demultiplexerchannelsmultiplexer,或者自己写。我倾向于重新实现多路复用,因为我认为这需要更改我们现有代码的更少。

在此之前,我正在做一些尽职调查,以确定多路复用是否甚至是一项重要的优化。

鉴于 Redis 支持的 Django 2 + Channels 2 应用程序在 Nginx 后面的负载平衡环境中使用 Daphne(目前主要计划SyncConsumers)和 Gunicorn,我认为将 websocket 连接数增加 3x-5x 只会微不足道地增加Redis RAM、应用服务器 RAM 和 Daphne CPU,而且浏览器 RAM 和 CPU 的增加也可以忽略不计,但这只是一个有根据的猜测。

  1. 我应该如何考虑每个额外的 WebSocket 连接 a.) 在 Django Channels v2 和 b.) 在浏览器中的成本?
  2. 我还没有看到任何设计为在单个页面上使用多个 WebSocket 连接的 Web 应用程序。你?如果是这样,它是高性能的吗?它使用了多少个连接?
  3. 你会怎么做?

解决相邻但不同问题的 Stack Overflow 帖子:

  1. How to use multiple websocket connections using Django Channels?
  2. Django Channels 2 implementing Multiplexer/Demultiplexer like Channels 1
  3. Reusing an existing websocket in Django Channels

【问题讨论】:

    标签: django-channels daphne


    【解决方案1】:

    作为channelsmultiplexer的作者,我希望我有一些有用的见解。

    使用 Channelv2 需要记住一件关键的事情,每个消费者实例都有 1 个运行循环,因此当它处理消息时将无法处理另一个消息(它们会排队)。特别是如果您对您的消费者采取了需要时间(db 或其他)的操作,则消费者在工作时将不会收到其他消息。使用channelsmultiplexer 时,阻塞不会影响其他多路复用消费者实例。如果您需要对channelsmultiplexer 进行更改/添加,请随时在 repo 上创建问题,我很乐意根据需要进行更改以适应更多人的用例。

    我应该如何考虑每个额外的 websocket 连接 a.) 在 Django Channels v2 和 b.) 在浏览器中的成本?

    是的,因为除非您的隧道 ws 通过 HTTP2(不是通道支持,但如果您确定所有客户端都是 http2,nginx 可以帮助您一年)用户浏览器可能会限制您可以打开的并发 HTTP 连接数.许多浏览器会将您限制为大约 7 个打开的连接,但这可能会随时更改,并且移动浏览器可能会更严格(它们往往是)

    【讨论】:

    • 如果我在负载均衡器后面有多个 daphne 实例,Channels v2 真的可以做到,因此每个用户只能进行一次同步操作吗?如果是这样,你能指出我在代码或文档中这样做的地方吗?
    • 不是每个连接,而是每个消费者。 (因此,除非您使用的多路复用器确实意味着每个连接都是肯定的)github.com/django/channels/blob/main/channels/consumer.py#L58 这个await_many_dispatch github.com/django/channels/blob/… 在L40 上,您可以看到它对所有可调用对象使用了相同的循环。
    • 它不是真正的同步操作,它们仍然是异步的(不阻塞其他消费者实例)但会阻止该消费者的其他消息。这样做的原因是您现在可以将状态存储在消费者实例上(它是一个常规类),因此同时运行多个读取/写入该状态的东西并不是一个好主意。
    • 感谢您提供所有这些信息;这非常有帮助,尽管我发现在 Channels v2 中使用正确的术语具有挑战性。 1. run-rooprun-loop 的 Scooby-Doo,对 ;) ? 2. 您提到每个 consumer instance 都有一个运行循环 - 这涵盖了一个 特定连接,例如一个用户,对吧? 3.channelsmultiplexer 使用AsyncJsonWebsocketConsumer 的子类。我的消费者需要使用 Django ORM,Channels v2 文档建议我应该 SyncConsumer 处理这种情况。我还能将channelsmultiplexerSyncConsumers 一起使用吗?
    • 1) 是的,抱歉(应该在我的手机上写这些东西)2) 你可以,SyncConsumer 基本上是异步消费者,所有生命周期方法都被包装为同步。多路复用器将是Async,但上游消费者可以是任何 JSON web-socket 消费者。
    猜你喜欢
    • 2022-01-12
    • 2021-07-03
    • 2019-05-03
    • 2019-02-26
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    相关资源
    最近更新 更多