1

我正在开发数据库设计工具(python、gevent-socket.io)。在这些工具中,多个用户可以讨论一个数据库模型,在运行时接收更改。为了支持这个特性,我使用了 socket.io。我想扩展轻松处理 socket.io 连接的服务器数量。最简单的方法是设置 nginx 根据模型 ID 选择服务器。

我想要模块方法,其中模型 ID 除以服务器数量。因此,如果我有 3 个节点,模型 1 将首先处理,2 - 在第二个,3 - 在第三个,4 - 在第一个等等。

我的模型加载请求看起来像 /models/,所以这里没有问题 - 可以解析参数以找到服务器来处理它。但是模型页面加载后,JS尝试建立连接:

var socket = io.connect('/models', {
            'reconnection limit': 4000
        });

它访问默认端点,因此服务器接收以下请求:

http://example.com/socket.io/1/xhr-pooling/111111?=1111111

为了处理它,我以这种方式创建应用程序:

SocketIOServer((app.config['HOST'], app.config['PORT']), app, resource='socket.io', transports=transports).serve_forever()

进而

@bp.route('/<path:remaining>')
def socketio(remaining):
    app = current_app._get_current_object()
    try:
        # Hack: set app instead of request to make it available in the namespace.
        socketio_manage(request.environ, {'/models': ModelsNamespace}, app)
    except:
        app.logger.error("Exception while handling socket.io connection", exc_info=True)
    return Response()

我想把它改成

http://example.com/socket.io/<model_id>/1/xhr-pooling/111111?=1111111

能够在 ngnix 中选择正确的服务器。怎么做?

更新

我还想在尝试建立连接时检查用户权限。我想用 socketio(remaining) 方法来做,但是,我需要再次知道他试图访问什么模型。

更新 2

我实现了权限验证器,从 HTTP_REFERER 获取 model_id。似乎,它只是包含模型标识符的请求的一部分(值示例:http ://example.com/models/1/ )。

4

1 回答 1

2

第一个想法 - 是告诉客户端当前时间可用的服务器。此外,您可以按优先级为客户端生成服务器列表,只需将它们按顺序放入 javascript 生成的数组中。这个答案意味着您的服务器可以回答任何模型,您可以通过更改新客户端生成列表中的服务器顺序来控制服务器加载。

我认为这是更灵活的方式。但是,如果您愿意 - 您可以在 nginx 中解析查询字符串并在任何底层服务器上路由请求 - 只需一个用于“模型 id-服务器端口”关系的表

更新:只是想你的任务。并找到另一种解决方案。当您生成客户端网页时,您可以在某处将内联服务器计数在 js 中。然后,当您请求模型更新时,只需使用创建为的另一个参数

serverId = modelId%ServersCount;

这将是 nginx 中路由的服务器标识符。然后在 nginx 配置中,您可以使用简单的解析查询字符串,并将请求路由到您可以通过 serverId 参数找到的服务器。

在“元语言”中,它将是

  1. 获取参数 serverId 到 var $servPortSuffix
  2. 将请求路由到 localhost:80$servPortSuffix

或其他路由想法。

您可以通过向 socket.io 添加其他 GET 参数

io.connect(url, {query: "foo=bar"})
于 2013-09-02T15:08:21.373 回答