首页 > 解决方案 > Webapp 服务器数据存储:内存 vs 数据库

问题描述

我们正在使用 MySQL 数据库在 Go 中制作一个 Web 应用程序。我们的用户一次只能有一个活跃的客户。就像 Spotify 一样,您一次只能在一台设备上收听音乐。为此,我制作了一张地图,其中用户 ID 为键,并且对他们的活动 websocket 连接的引用作为值。根据客户端必须在请求标头中发送的 websocket id,我们可以识别请求来自其活动会话的天气。

我的问题是将数据(在这种情况下是带有用户 ID 和 websocket 的地图)存储在全局空间中是否是一种好习惯,或者将其存储在数据库中是否更好。

我们预计不会同时达到 10000 多个活跃客户。平均应该在1000左右。

标签: databaseperformancegomemorywebsocket

解决方案


如果您只运行一个 websocket 服务器实例,将其存储在内存中就足够了。因为如果它由于某种原因关闭/重新启动,那么所有连接都将丢失,所有客户端都必须再次创建它们(因此连接列表将再次由所有想要使用该服务的客户端填充) .

但是,如果您计划水平扩展它以便在负载均衡器后面有多个 websocket 服务,那么连接可能需要存储在某种数据库中。并不是因为它必须更加持久,而是因为您需要能够针对所有服务连接检查请求。

也可以有一个单独的服务来处理传入的请求,并询问所有的 websocket 服务是否有请求中指定的连接。如果您添加一个 pub/sub 队列,并且每个 websocket 服务都为其所有 websocket id 订阅通道,并且接收请求的服务然后发布 websocket id,并且 websocket 服务可以在单独的通道上发回回复,则可以做到这一点如果他们有这种联系。如果没有人响应(没有 websocket 服务具有 websocket id),您必须决定如何处理。要么渠道不存在,要么您希望在特定时间内得到答复。或者您可以发布关于一般主题的问题,并期望所有 websocket 服务都回复(是或否)。

关于你是否需要扩展它,我猜主要取决于你运行服务的底层服务器。如果我理解正确,websocket 服务基本上不会做任何事情,除了跟踪它的连接(你应该添加一些乒乓球来发现连接是否丢失)。那么你的限制应该主要是你的系统可以一次处理多少个文件描述符。如果该限制远大于您预期的最大用户数,那么仅运行一台服务器并将所有内容存储在内存中可能是一个不错的解决方案!

最后,如果您的业务是为所有用户打开 websocket,为什么不通过该 websocket 连接进行所有“其他”通信,而不是让他们发送带有 websocket id 的 HTTP 请求?也许 HTTP 更适合您的用例,但可能需要考虑 :)


推荐阅读