15

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

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

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

Memcache——至少内存可以从所有虚拟机全局访问,但现在由于不活动和内存压力,放弃一个非常可行的通道的可能性可能更大。

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

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

4

2 回答 2

8

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

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

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

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

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

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

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

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

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

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

于 2011-12-21T08:41:31.950 回答
2

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

Google App Engine 频道可以重复使用吗?

于 2013-07-05T19:49:39.310 回答