如何使用googleappengine跟踪页面视图?

2024-04-25 11:47:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个允许用户提交博客文章的网络应用程序。我想跟踪每个博客文章页面的页面浏览量。因此,当一些访问:

/post/123

用户的访问者应该看到访问过此页面的人数。你知道吗

我想到的一个似乎无法扩展的解决方案是在Blog类型中添加一个page\u views属性:

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

然后,每当访问页面时,只需执行blog.page_views加1即可。然后blog.put()。但是,这种尝试意味着我们将过于频繁地向db写入数据。你知道吗

有更好的办法吗?你知道吗


Tags: 用户程序文章page网络应用blog页面解决方案
2条回答

如果您的目的是获得非常准确的页面视图计数是的,那么您必须将其保存在数据存储中,并且必须解决超过最大实体组写入速率~1/秒的风险。本例中的典型方法是Sharding counters。你知道吗

但是,如果您对偶尔可能丢失一些视图(IMHO完全可以接受)感到满意,那么您可以使用不同的策略,使用memcache存储计数器和时间戳,您可以对其进行调整,使其在数据存储操作方面更加轻松。在每个页面视图上,您都会调用一个事务函数(以防止损坏数据存储计数器值),该函数将:

  • 增加memcache计数器值(如果缺少或无效,则将其设置为1)
  • 检查memcache timestamp值,如果有效并且“足够近”(可调),它将返回,否则继续
  • 用当前时间更新memcache时间戳(以防止与下一步一起使用为另一个并发请求调用的相同函数的争用条件)
  • 将memcache counter值添加到datastore counter值并保存datastore counter;如果此事务失败,则表示其他并发请求已经在执行此操作,无需执行任何操作(函数将在此时结束)
  • 将memcache计数器重置为零
  • 可选,如果您不希望有足够长的非活动期(在此期间可能会丢失内存计数器中积累的大量视图,这些视图可能随时消失),则不需要排队等待延迟的任务(或延迟的任务,如果您希望使用延迟的库),该任务也会调用相同的事务函数,除了那次跑步:
    • 它不会增加memcache计数器的值
    • 它不会让另一个延迟的任务排队

我会选择任务延迟值等于“最近足够”值。你知道吗

通过调整“足够新”值,可以控制更新数据存储计数器值的频率。你知道吗

当您想显示视图的数量时,您只需读取datastore值和memcache值(按此顺序,以防止可能的争用情况,在这种情况下,您需要对memcache计数器值进行两次计数),然后将它们相加即可获得访问计数。你知道吗

由于ndb中的一致性问题,写入数据存储中的计数器可能非常不准确,尤其是当你的应用程序获得大量流量时。您的一个实例可能读取1234page_views的当前计数,然后尝试将1235写入数据存储。但是,在此期间,可能其他访客也来了,他们都会看到相同的page_views值。另外,由于一致性,您获得的读数可能会过时一分钟。所以,你的1235可能是1278,甚至更大。你知道吗

为了避免这么多的写操作,请考虑在memcache中创建计数器,然后增加那里的计数。Memcache跨实例持久存在,值几乎是瞬间变化的。然后,定期将Memcache计数转储到数据存储,并在其中递增,然后将其删除。你知道吗

例如,每当访问者查看post时,增加memcache计数,并在5分钟后设置一个延迟任务,以将计数持久化到数据存储中。这样,你就可以在一个写操作中收集5分钟的视图

Memcache很容易失败,所以您的计数永远不会100%准确。但是,每5分钟左右倾倒一次可以减少误差。你知道吗

相关问题 更多 >