我们有一个 Django Channels 应用程序,简而言之,它的功能是这样的
- 客户端发出 /start HTTP 请求返回一个唯一的 id,比如 123。这个唯一的 id 被写入数据库
- 客户端发出 /start/123 WS 请求,该请求由通道消费者处理,以在确认数据库中确实存在 id 123 后创建网络套接字
- 客户端发出/message/123 HTTP请求,服务器在确认id 123有效后立即以200OK响应,但在进行必要的处理后,在相应的web-socket上异步响应此消息
- 客户端等待读取网络套接字上的响应
Channels 层是 Redis,所有数据库调用都包装在 sync_to_async 中,THREAD_SENSITIVE 为 True。
我们希望支持 25,000 个并发用户/客户端。我们使用以下设置进行测试,都是 Ubuntu 机器。
为了模拟负载,我们尝试了一个简单的 Python 负载模拟器。这就是它的作用
- 在新线程中,进行 /start 调用
- 根据第一次调用的响应,进行/start/unique-id WS调用
- 同时(真):
进行 /message/unique-id HTTP 调用
等待网络套接字上的响应
睡眠(1 到 5 秒)
它配置了要生成的线程数和所有线程开始访问服务器的初始启动时间。
问题是,我们很难扩展到 2,000 个用户。即使有 2,000 个线程(来自一台机器的 1000 个线程)负载模拟器,我们也会看到 HTTP 调用失败、网络套接字超时等问题。我们实际上用绝对精简版的应用程序尝试过这个,但结果相同。所有机器上的 ulimit 都设置为足够高的数字 (65000)。如果有人有任何扩展此类应用程序的经验,将有助于了解
- 如果这是正确的设置方法
- 如何配置 NGINX(我们使用 8 个 worker)以获得最佳性能
- uvicorn有什么具体的配置可以帮助
- THREAD_SENSITIVE 值应该是多少,我们尝试了两者,但或多或少相似的结果
~弥敦道