如何使用谷歌应用引擎跟踪页面视图?

时间:2018-01-11 16:20:13

标签: python google-app-engine analytics app-engine-ndb

我有一个网络应用程序,可以让用户提交博客文章。我想跟踪每个博客帖子页面的页面浏览量。所以当一些访问:

/post/123

用户的访问者应该会看到访问此页面的人数。

我想到的一个看似不可扩展的解决方案是将一个page_views属性添加到Blog类:

class Blog(ndb.Model):
    title = ndb.StringProperty()
    page_views = ndb.IntegerProperty()

然后,每当访问该页面时,只需blog.page_views加1.然后blog.put()。但是,这种尝试意味着我们会过于频繁地写入数据库。

有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

由于ndb中的一致性问题,写入数据存储区中的计数器可能非常不准确,尤其是当您的应用程序获得大量流量时。其中一个实例可能会读取当前计数1234 page_views,然后尝试将1235写入数据存储区。但是,与此同时,其他访问者可能会来,并且他们都会看到相同的page_views价值。另外,由于一致性,您获得的读数可能只是一分钟陈旧。所以,你的1235实际上可能是1278,甚至更大。

要避免这么多写操作,请考虑在memcache中创建计数器,然后在那里增加计数。 Memcache持续跨越实例,并且值几乎立即发生变化。然后,定期将Memcache计数转储到数据存储区,在那里递增,然后将其删除。

示例,每当访问者查看帖子,增加内存缓存计数,并在5分钟后设置延迟任务以将计数持久保存到数据存储区。这样,你可以在一个写操作中收集5分钟的观看次数。

Memcache容易出现故障,因此您的计数永远不会100%准确。但是,每5分钟左右倾倒可以减少错误。

答案 1 :(得分:0)

如果您打算使用非常准确的页面浏览计数,则必须将其保留在数据存储区中,并且您必须解决超过最大实体组写入速率的风险〜 1秒。在这种情况下,典型的方法是Sharding counters

但是,如果您可以偶尔遗漏一些视图(恕我直言可以完全接受),您可以使用不同的策略,使用memcache存储计数器和时间戳,您可以调整,以便在数据存储区操作方面更加轻松。在每个页面视图中,您都可以调用事务功能(以防止破坏数据存储计数器值),这将是:

  • 增加memcache计数器值(如果丢失或无效,则将其设置为1)
  • 检查memcache时间戳值,如果有效且"最近足够" (可调)它只是返回,否则继续
  • 使用当前时间更新memcache时间戳(以防止与下一步一起使用为另一个并发请求调用相同函数的竞争条件)
  • 将memcache计数器值添加到数据存储计数器值并保存数据存储计数器;如果此事务失败,则意味着其他一些并发请求已经执行,无事可做(该功能将在此时结束)
  • 将memcache计数器重置为零
  • 可选,如果你没有预料到足够长的不活动期,你可能会失去在内存计数器中积累的大量观点,这些观点可能随时消失 - 排队延迟任务(或延迟任务) ,如果你更喜欢使用延迟库),它也会调用同一个事务函数,除了在那个运行中:
    • 它不会增加内存缓存计数器值
    • 它不会排队另一个延迟任务

我选择的任务延迟值等于"最近的"之一。

通过调整"最近的"值,您可以控制更新数据存储计数器值的频率。

当您想要显示视图数量时,您只需读取数据存储区值和内存缓存值(按此顺序,以防止可能的竞争条件,其中您将对memcache计数器值进行两次计数并添加它们以获得访问次数。