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

dep*_*ner 15 google-app-engine channel pooling channel-api

似乎使GAE Channel API具有财务可行性的唯一方法是实现某种池化机制(其中一位高级应用程序引擎产品经理甚至告诉我这一点,当我通过电子邮件向他们发送关于价格过高的价格时)来重用尚未使用的渠道过期.

我一直在集思广益,以实现渠道池,但我认为每种方法都有一些非常严重的缺点.

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

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

后端实例 - 可能性是可靠性方面的最佳选择,但现在运行后端的费用将耗尽首先实现池的所有节省!

是否有更好的地方/方式在虚拟机上实现我缺少的通道池,或者我是否不必要地在这里选择我的选项的缺点?我真的希望有,或者看起来我的应用程序将不得不恢复到轮询(在我的初步指标中看起来略微便宜).

Sud*_*han 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)
Run Code Online (Sandbox Code Playgroud)

执行:

  • 存储client_id和token在实体,状态指示是否它被使用,最后平时间和创建时间.让我们client_id成为关键.还要考虑使用NDB.免费memcaching.

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

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

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

每隔[heartbeat]秒运行一次task/cron,找到一段时间没有ping的令牌 - 并将它们设置为未使用.

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

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

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