我已经阅读了很多关于计数器的GAE文章和GAE中令人讨厌的写入限制.我已经看到了带有分片,cron任务,内存缓存等的解决方案.然后我学到了足够多的java线程能够提出问题:
Q: Can we implement a counter in servlet threads using concurrency /
servlet static varibales?
这将带来额外的好处,即减少对数据存储区和内存缓存的写入(花费相同的$),并删除cron要求,因为一系列快速计数器命中中的最后一个servlet将更新数据存储区.
我不太了解并发编程以提出解决方案,但我想象一下静态servlet变量,可能是“atomic-integers”和last-update标志,以便检查这个servlet是否是最后一个更新servlet的servlet static var,在最后200ms内,从而触发对数据存储区的保存.
// Servlet gets a hit
// static var counter++
// Checks last datastore save time of the static var, if longer than 200ms
// save to datastore & save "last update time"
// If shorter than 200 ms ago, let the next servlet call update the datastore
可以这样做吗?有什么建议? Mucho赞赏你的想法.
解决方法:
只是详细说明我的评论:
您可能已经意识到,App Engine会在达到某个流量阈值时启动应用程序的新实例.鉴于新实例可以在完全不同的服务器上运行,您的静态计数器将变为无效.
现在只是为了澄清,在App Engine中实现计数器的正确方法是使用Sharding并将其拆分为多个entite.
现在假设您希望最小化数据存储区调用,您可以使用memcache存储计数器数据并以指定的频率将其写入数据存储区(例如通过cron).您的memcache数据将在您应用的所有实例中保持一致.
在memcache发生故障的情况下,你当然会冒失去memcache计数器的风险,但这就是把它写到数据存储区的工作.同样,这不是一个100%万无一失的解决方案,分片是;但这是最小化数据存储区调用的一种方法.