使用socketio和flask制作的应用程序的负载平衡/路由

Bob*_*emi 3 load-balancing nginx flask socket.io flask-socketio

在部署网络应用程序方面,我有点菜鸟,并且想确保我正在构建的小应用程序能够与我尝试使用的技术配合使用。

我对 Flask 有一些经验,但只使用过测试服务器。我的理解是,使用 nginx 或 apache,如果我编写一个 Flask 应用程序,访问我网站的每个用户都可以获得 Flask 应用程序的不同实例,具体如何工作让我有点困惑。

我想要制作的应用程序类似于聊天室/类似“我们之间”的游戏。当用户访问该网站时,他们会加入一个大“大厅”,并且可以加入已经存在的“房间”,或者启动一个新房间并生成一个代码/ID,他们可以将其传递给他们的朋友,以便他们的朋友可以加入同一个会话(我认为可以使用 socketio“房间”)。

但是,如果每个客户端都连接到自己的 Flask 实例,那么每个服务器实例是否都能够看到其他实例上的“房间”?假设我的应用程序变得非常流行,并且我想将来在多台机器/AWS 实例上扩展大厅,我现在可以做些什么来确保它有效吗?或者就 Flask-socketio/nginx 堆栈而言,跨多台机器的扩展相当于跨单台机器上的实例的扩展。

基本上,我如何确保代码的大厅部分是可扩展的。我需要做些什么来确保每个用户都能够与其他用户连接到房间,即使他们获得了不同的 Flask 应用程序实例?

Mig*_*uel 5

我将专门针对 Socket.IO 服务来回答这个问题。您使用的应用程序或第三方服务的其他功能可能需要它们自己的水平扩展支持。

使用 Flask-SocketIO 从一个实例扩展到两个或更多实例时,需要一个额外的部分,即消息队列,通常是 Redis 或 RabbitMQ,尽管还有更多选项。

正如您在问题中明确指出的那样,当整个服务器处于单个实例中时,诸如每个连接的客户端所在的房间之类的数据可以在托管应用程序的单个进程的内存中轻松获得。

当您扩展到两个或更多实例时,您的客户端将被分区并随机分配到您的一台服务器。因此,您最终可能会让房间中的参与者也分布在多个服务器上。

为了使事情正常进行,服务器实例都连接到消息队列并使用消息来协调复杂的操作,例如向房间广播。

简而言之,要从一个实例扩展到多个实例,您所需要做的就是部署一个消息队列,并更改 Flask-SocketIO 服务器以指示队列的位置。例如,这是单实例服务器实例化:

from flask_socketio import SocketIO

socketio = SocketIO(app)
Run Code Online (Sandbox Code Playgroud)

下面是在本地主机的默认 6379 端口上运行的 Redis 消息队列的初始化:

from flask_socketio import SocketIO

socketio = SocketIO(app, message_queue='redis://')
Run Code Online (Sandbox Code Playgroud)

应用程序代码不需要更改,Flask-SocketIO 通过在队列上发布消息来为您完成实例之间的所有协调。

请注意,实例托管在同一服务器还是不同服务器中并不重要。重要的是它们连接到同一个消息队列以便它们可以通信。