我正在创建一个小型服务,我经常(大约每5秒左右)轮询100个帐户(在类似Twitter的服务中)来检查新消息,因为该服务尚未提供流API(就像Twitter实际上那样。)
在我看来,我的架构计划为每个用户每隔5秒排队Ticker
。一旦勾选,我就会对服务进行API调用,检查他们的消息,并将SELECT
调用到我的Postgres数据库以获取特定的用户详细信息并检查最新消息的日期,以及是否有更新的消息比UPDATE
条目更新并通知用户。重复广告。
我对后端的东西和架构都不是很有经验,所以我想确保这不是一个绝对荒谬的设置。对数据库的调用量是否合理?我在滥用goroutines吗?
答案 0 :(得分:1)
让我回答你的描述。
我想确保这不是一个绝对荒谬的设置。
我理解以下内容。对于每个用户,您在一个goroutine中每5秒创建一个滴答。另一个goroutine消耗这些标记,执行轮询并将最后一条消息的日期与您在PostgreSQL数据库中记录的日期进行比较。
答案是:这取决于。您拥有多少用户以及您的应用程序可以支持多少用户?根据我的经验,回答这个问题的最佳方法是衡量应用程序的性能。
对数据库的调用量是否合理?
这取决于。为了给你一些保证,我看到一个PostgreSQL数据库每秒需要数百SELECT
。我没有看到设计错误,因此对应用程序进行基准测试是可行的方法。
我在滥用goroutines?
你的意思是执行太多了吗? I think it is unlikely that you are abusing goroutines that way.如果您认为可能存在特殊原因,则发布相应的代码段会使您的问题更加准确。
答案 1 :(得分:1)
您可以随时进行优化,在您需要客户端吞吐量的情况下,您可以使用一堆众所周知的优化,例如切换到反应模型,添加一些缓存服务器,将负载分散到多个数据库从站,... 。
您应该大规模测试您的解决方案,如果它符合您在用户吞吐量和服务器成本方面的需求,那么您的解决方案是正确的。
答案 2 :(得分:1)
您提出的解决方案:每个用户每5秒钟进行一次查询。拥有100个用户是:
1 * 100 / 5 seconds = 20 queries / second
如果查询速度很快,这不会被视为大负荷。
但为什么你需要分别为每个用户做这个?如果您需要以5秒的粒度获取更新,您可以每5秒执行一次查询,该查询不会被用户过滤,但会检查来自所有用户的更新。
如果上述查询给出了结果,您可以迭代结果并为最近5秒内有更新的每个用户执行必要的操作。这导致:
1 query / 5 seconds = 0.2 query / second
查询次数减少了一百倍,仍以相同的时间粒度为您提供所有更新。
如果要为更新执行的任务很长或依赖于外部系统(例如,调用另一台服务器),您可以在单独的goroutine中执行这些任务。您可以选择为每个任务启动新的goroutine,也可以选择使用这些排队任务的工作器goroutine池,并将任务排队(使用通道)。