建议的 Golang 架构,用于频繁轮询用户帐户

Suggested Golang architecture for polling user accounts frequently

我正在创建一个小型服务,我经常(每 5 秒左右)轮询大约 100 个帐户(在类似 Twitter 的服务中)以检查新消息,因为该服务尚未提供流媒体API(就像 Twitter 所做的那样)。

在我的脑海中,我将架构计划为每个用户每 5 秒排队 Tickers。一旦滴答声响起,我就会对服务进行 API 调用,检查他们的消息,然后调用 SELECT 到我的 Postgres 数据库以获取特定用户的详细信息并检查最新消息的日期,如果有比 UPDATE 条目更新的消息并通知用户。重复广告令人作呕。

我在后端事物和架构方面不是很有经验,所以我想确保这不是一个绝对荒谬的设置。对数据库的调用量是否合理?我在滥用 goroutines 吗?

根据你的描述让我回答。

I want to make sure this isn't an absolutely absurd setup.

我明白以下内容。对于每个用户,您在一个 goroutine 中每 5 秒创建一个 tick。另一个 goroutine 使用这些滴答,执行轮询并将最后一条消息的日期与您在 PostgreSQL 数据库中记录的日期进行比较。

答案是:视情况而定。您有多少用户,您的应用程序可以支持多少用户?根据我的经验,回答这个问题的最佳方法是衡量应用程序的性能。

Is the amount of calls to the database sensible?

视情况而定。为了给你一些保证,我看到一个 PostgreSQL 数据库每秒需要数百 SELECT。我没有发现设计错误,因此对您的应用程序进行基准测试是可行的方法。

I am abusing goroutines?

你是说喜欢执行太多? I think it is unlikely that you are abusing goroutines that way. 如果您出于某种特殊原因认为可能是这种情况,发布相应的代码片段可以使您的问题更加准确。

  • 您的架构是最有效的方式吗? 没有.
  • 你现在应该做点什么吗? ,您应该测试您的解决方案。

您始终可以通过优化进行更深入的研究,在您的情况下,您需要客户端吞吐量,因此您可以使用一系列众所周知的优化,例如切换到反应模型、添加一些缓存服务器、将负载分散到多个数据库从属服务器上, ...

您应该大规模测试您的解决方案,如果它在用户吞吐量和服务器成本方面满足您的需求,那么您的解决方案就是正确的。

您建议的解决方案:每个用户每 5 秒查询 1 次。有 100 个用户是:

1 * 100 / 5 seconds = 20 queries / second

如果查询很快,这不算大负载。

但是为什么需要为每个用户单独执行此操作?如果您需要以 5 秒的粒度获取更新,您可以每 5 秒执行 1 个查询,该查询不按用户过滤,而是检查来自 all 用户的更新。

如果上述查询给出了结果,您可以遍历结果并对在过去 5 秒内有更新的每个用户执行必要的操作。这导致:

1 query / 5 seconds = 0.2 query / second

查询减少了一百倍,仍然以相同的时间粒度为您提供所有更新。

如果要执行的更新任务很长或依赖于外部系统(例如调用另一台服务器),您可以在单独的 goroutine 中执行这些任务。您可以选择为每个任务启动一个新的 goroutine,或者您可以有一个工作 goroutines 池来使用这些排队的任务,并且只将任务排队(使用通道)。