Google App Engine 中的最佳渠道池化方法

Posted

技术标签:

【中文标题】Google App Engine 中的最佳渠道池化方法【英文标题】:Best Method of Channel Pooling in Google App Engine 【发布时间】:2011-12-30 03:20:35 【问题描述】:

似乎使 GAE Channel API 在财务上可行的唯一方法是实施某种池机制(一位高级应用引擎产品经理甚至在我向他们发送有关高昂价格的电子邮件时告诉我这一点)以重用渠道还没有过期。

我一直在思考实现频道池的方法(地点),但我想到的每种方法都有一些非常严重的缺点。

Servlet 的静态内存 -- 很好,但是当新的 VM 实例打开和/或客户端从一个 VM 传递到另一个 VM 时,会丢弃相当多的开放通道。

Memcache -- 至少内存可以从所有 VM 全局访问,但现在由于不活动和内存压力,丢弃非常可行的通道的可能性可能更大。

后端实例 -- 就可靠性而言,这可能是最好的选择,但现在运行后端的费用将首先耗尽实施池的所有节省!

是否有更好的地方/方式来跨我缺少的虚拟机实施通道池,或者我是否在此处不必要地挂断了我的选项的缺点?我真的希望有,或者看起来我的应用将不得不恢复轮询(在我的初步指标中看起来稍微便宜一些)。

【问题讨论】:

您可以将它们存储在带有时间戳的数据存储中,然后运行 ​​cron 来删除过期的吗?虽然读/写操作也会花费您... @Jonathan Newmuis 是的,这与 Memcache 解决方案相得益彰,但就像您提到的那样,这当然不是没有成本的。也许他们两个一起工作是最可行的选择......有人有任何指标或经验吗? 您能补充一些关于您的软件功能的信息吗? @alfa64 我的应用程序是一款大型多人社交游戏,可将关键游戏状态更新实时动态推送到特定客户端。问题是,一个通常的用例涉及一个球员在签字前登录几分钟,最多可能是 15 分钟。这实际上浪费了应用引擎上至少 85% 的(目前)最昂贵的资源,尽管它具有出色的功能,但它完全不可行。 现在频道创建似乎是免费的,所以如果只关心财务可行性,这应该不再是问题。 【参考方案1】:

这就是我要做的(在看到你的问题后,我实际上正在考虑编写这个库。我也需要它):

使用以下 API 创建一个 taskpool 模块。

client_id, token = taskpool.get()

# Setup a heartbeat in the client JS, maybe every minute. 
# Also call this every time the client indicates presence
taskpool.ping(client_id)

taskpool.release(client_id)

实施:

client_idtoken 存储在一个实体中,其状态指示它是否正在使用、上次ping 时间和创建时间。让client_id 成为关键。还可以考虑使用NDB。免费内存缓存。

get() 检查是否有未使用的令牌,如果找到则返回一个。否则创建一个新的,存储并返回它。

ping() 更新该令牌的最后一次 ping 时间。不是轮询,而是让客户端在每个 [heartbeat] 时间发送一个 ping。

release() 将令牌标记为未使用。

每隔 [heartbeat] 秒运行一次任务 / cron 以查找有一段时间没有收到 ping 的令牌 - 并将它们设置为未使用。

当客户端报告关闭令牌时,执行get()

但请记住,安全性损失是任何类型的代币池的副产品。如果恶意客户端持有令牌并停止发送心跳,那么一旦令牌被重新使用,它可能稍后能够监听传递给新客户端的消息。如果您在完全公开的网站上,这不是问题,但请记住这一点。

如果我把它写成一个库,我会更新这个答案。

【讨论】:

感谢 Sudhir 的创意回答,但 NDB 是什么?据我所知,现有的 App Engine Memcache API 已经免费了吗?这听起来绝对是一个可行的、功能齐全的解决方案,但我很想看看这些多个移动部分(crons/任务和数据存储操作)是如何执行的。如果您最终启动了一个库,请告诉我们(特别是如果您打开了一个开源存储库:))。 NDB 是 1.6.0 以后的新数据存储 API:code.google.com/p/appengine-ndb-experiment。用链接更新了答案。 哦,我所说的“免费内存缓存”是指 NDB 会为您处理缓存。没有额外的代码行。 啊,我明白了。我最终可能会按照您描述的方式实现“通道池”库,但使用 Java 而不是 Python(因为我的应用程序使用了 Google 的 GWT,因此 Python 库对我的目的不可行)。如果我这样做了,我会用即将到来的 repo 的链接更新这个问题。 听起来不错...我还意识到 Channel API 现在提供了状态处理程序 - 它们应该可以更轻松地跟踪发布。【参考方案2】:

根据 Google App Engine 支持团队的说法,频道令牌可能无法重复使用。预计不会重复使用它们。

Can Google App Engine Channels be reused?

【讨论】:

以上是关于Google App Engine 中的最佳渠道池化方法的主要内容,如果未能解决你的问题,请参考以下文章

从 Google App Engine 中的数据存储区获取实体以在 iOS 应用中使用

Google Cloud 中的 Google Compute Engine、App Engine 和 Container Engine 有啥区别?

探索Google App Engine背后的奥秘- 总结

在 Google App Engine 数据存储中存储分层数据?

如何使用 Google App Engine 管理第三方 Python 库? (虚拟环境?点子?)

google-app-engine:google api python客户端hello world中的ImportError httplib2