问题:负载均衡/路由一个使用socketio和flask制作的应用

在部署 Web 应用程序方面,我有点菜鸟,我想确保我正在构建的一个小应用程序能够与我正在尝试使用的技术一起使用。

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

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

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

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

解答

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

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

正如您在问题中明确指出的那样,当整个服务器位于单个实例中时,每个连接的客户端所在的房间等数据在托管应用程序的单个进程的内存中很容易获得。

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

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

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

from flask_socketio import SocketIO

socketio = SocketIO(app)

这是在 localhost 的默认 6379 端口上运行的 Redis 消息队列的初始化:

from flask_socketio import SocketIO

socketio = SocketIO(app, message_queue='redis://')

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

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

Logo

开发云社区提供前沿行业资讯和优质的学习知识,同时提供优质稳定、价格优惠的云主机、数据库、网络、云储存等云服务产品

更多推荐