java - 如何向所有 Google App Engine 实例广播数据?

标签 java performance google-app-engine memcached publish-subscribe

为简单起见,假设我的应用需要允许数千名用户查看聊天室的实时只读流。主持人可以键入消息,但其他用户不能——他们只能实时看到主持人键入的内容。想象一下,用户正在观看一场体育赛事的文字解说。

每个用户通过对 GAE 服务器的简单 /get-recent-messages 调用每秒轮询一次来检查新消息。 (在你问之前,我相信使用 Google 的 Channels API 太贵了。)

考虑到这个应用程序被成千上万的用户同时使用,这意味着数十到数百个 GAE 实例正在运行,我如何才能让这些 /get-recent-messages 调用返回最新的聊天室消息延迟小于 1000 毫秒,同时最大限度地减少服务器负载和 GAE 成本?

我的一些想法:

  1. 将聊天消息存储在数据存储实体中。
    • 显然这太慢且代价高昂,尤其是在使用查询/索引的情况下
  2. 将聊天消息存储在内存缓存键中。我想我会使用一个键来存储最后 50 条消息的键列表,然后再使用 50 个键,每条消息一个。
    • 这会造成巨大的瓶颈,因为 App Engine 的内存缓存按键进行分片,因此所有 500 个实例将不断地从相同的内存缓存键和相同的内存缓存服务器读取数据。
  3. 将聊天消息存储在实例内存中,由 memcache 支持。并在实例内存过时时从 memcache 中提取信息(如 #2 中所示)。
    • 当多个请求看到陈旧的实例内存缓存并同时从内存缓存中提取时,这可能会导致代价高昂的竞争条件。
  4. 使用后台线程从 memcache 更新实例内存。这可以使用在预热请求中启动的线程为每个实例每秒运行一次。它会像#3 一样工作,但只有一个线程拉动而不是随机请求触发内存缓存读取。
    • 我不认为 App Engine 上的后台线程是这样工作的。我也不知道这是否适合使用预热请求。
  5. 使用 Google's Pub/Sub service .
    • 我不知道它是如何工作的,对于这个用例来说它似乎有点过分了。
  6. 每秒运行一次 cron 作业以从内存缓存中提取数据。这与 #4 类似,只是不依赖后台线程。
    • 我需要它在每个 实例每秒 上运行。我不相信 cron/taskqueue API 有办法在所有 Activity 实例上运行作业或任务。

想法?

最佳答案

你应该检查this video . 我会选择内存缓存/数据存储版本和少量缓存(1-2 秒),这样您就可以减少为流量提供服务所需的实例数量。 如果您仍然需要 100-500 个实例来为您的流量提供服务,我仍然会选择内存缓存/数据存储版本。如果内存缓存是您的瓶颈,请将其分成 10 个键。

另一种解决方案是使用 Compute Engine 和网络服务器,您可以通过套接字连接用户。您可以通过 HTTP 与您的计算实例通信并将值存储在内存中,也可以使用拉取队列。

如果您真的需要与所有实例通信,请查看 communicating between modules

发布/订阅可能是您在发布新消息的实例和读取新消息的实例之间进行通信的一个不错的选择。根据我在 docs 中阅读的内容,您也应该能够将您的用户直接订阅到 Pub/Sub(仅拉取)。

关于java - 如何向所有 Google App Engine 实例广播数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33072075/

相关文章:

Java:覆盖非继承类的方法

java - 无法在android drawable xml中添加属性原色

Java 图形用户界面库

c - 快速二进制解析器算法

php - 适用于 PHP/MySQL 的 App Engine 替代品

python - Google App Engine 作为移动应用程序的身份验证服务器

java 声音,fadeIn 效果,使用 FloatControl

sql - SSIS 预评估阶段需要很长时间

c# - (DbContext) SaveChanges() 如何用于大量记录? - 寻求和找到最佳性能的解决方案

google-app-engine - 将 AppEngine/Go Users API 与 OAuth : code sample, 工作流一起使用,有什么帮助吗?