简体   繁体   English

在高流量Web应用程序中记录页面视图的最佳解决方案

[英]Best solution for recording page views in a high traffic web app

I'm building a web based directory for a niche industry. 我正在为利基行业构建一个基于Web的目录。 I would like to provide a views counter on each listing/profile, similar to how MySpace use to do it in the good old days (come back 90's MySpace, all is forgiven). 我想在每个列表/配置文件上提供一个视图计数器,类似于MySpace在过去的好时光中使用它的方式(回到90年代的MySpace,一切都被原谅)。

I'm using MySQL, and wondering what is the best way to record the data. 我正在使用MySQL,并想知道记录数据的最佳方法是什么。

Another thread ( What is the best way to count page views in PHP/MySQL? ) provided the following solution by @dorkitude: 另一个线程( 在PHP / MySQL中计算页面视图的最佳方法是什么? )由@dorkitude提供了以下解决方案:

$sample_rate = 100;
if(mt_rand(1,$sample_rate) == 1) {
    $query = mysql_query(" UPDATE posts SET views = views + {$sample_rate} WHERE id = '{$id}' ");
    // execute query, etc
}

This works on the theory of probability, and was explained by @Suyash as 这适用于概率论,并由@Suyash解释为

The general idea behind this is that, in theory, it should take 100 tries to hit the number '1' - and so the view count is more or less correct without the constant need to query the database. 这背后的一般思想是,理论上,它应该花费100次尝试来命中数字'1 - 因此视图计数或多或少是正确的,而不需要查询数据库。

The thread is dated 2011, and I was wondering if any better solutions had come to light since then. 该帖子的日期是2011年,我想知道从那时起是否有任何更好的解决方案。

Firstly, ensure tracking is done asynchronously. 首先,确保跟踪是异步完成的。 Do not perform tracking during page rendering. 在页面呈现期间不要执行跟踪。 Call the tracking script using javascript after the page has loaded. 页面加载后使用javascript调用跟踪脚本。

Using a sample rate will certainly help performance but will reduce accuracy for lower volumes, especially a sample rate of 1 in 100. Perhaps you could reduce the sample rate at low counts. 使用采样率肯定会有助于提高性能,但会降低较低音量的准确度,尤其是100的采样率。也许您可以在低计数时降低采样率。 eg For the first 1000 page views track every single view (disable sampling). 例如,对于前1000个页面视图,跟踪每个视图(禁用采样)。 After that use a sample rate of 100. Do NOT do this by looking up the counts in mysql. 之后使用100的采样率。不要通过查找mysql中的计数来执行此操作。 You need to pass through the pageviews counts (or equivalent sample rate) when calling the asynchronous tracking script. 调用异步跟踪脚本时,需要通过浏览量计数(或等效采样率)。

If you have a huge number of records in the posts table, the WHERE lookup will add overhead. 如果posts表中有大量记录,WHERE查找将增加开销。 Consider inserting a tracking record in another dedicated tracking table. 考虑在另一个专用跟踪表中插入跟踪记录。 Then you can periodically (nightly) update posts.views by summing all the tracking records. 然后,您可以定期(每晚)通过汇总所有跟踪记录来更新posts.views。

You could also consider an approach which periodically processes and aggregates your web server logs. 您还可以考虑定期处理和聚合Web服务器日志的方法。 This could be particularly efficient since you are probably logging all page views anyway. 这可能特别有效,因为您可能无论如何都要记录所有页面视图。

The code below is similar to the one you refer to but instead of relying on probabilities to update the database it stores the count in a file and updates the db whenever the file counter reaches a certain number. 下面的代码类似于您所引用的代码,但它不是依赖于更新数据库的概率,而是将计数存储在文件中,并在文件计数器达到某个数字时更新数据库。

It's slower than the method you referred to but it's faster than updating a counter stored in the db for every page view especially in setups with multiple web servers and a single db. 它比你提到的方法慢,但它比为每个页面视图更新存储在数据库中的计数器更快,特别是在具有多个Web服务器和单个数据库的设置中。

$update_rate = 100;
$file = "/my_counters/page_view_counter_$id";

if(!file_exists($file)) {
    file_put_contents($file,0);
}

$fp = fopen($file,"r+");

//acquire lock on counter file
//increment counter by 1
//if counter is equal to update rate, update count in db
//and reset counter to 0
if(flock($fp, LOCK_EX)) {
    $count = fread($fp, filesize($file));

    if(++$count >= $update_count) {      
        $count = 0;
    }

    rewind($fp);
    fwrite($fp,$count);
    flock($fp,LOCK_UN); //release lock on counter file
}

if($count == 0) {
    $query = mysql_query(" UPDATE posts SET views = views + {$update_rate} WHERE id = '{$id}' ");
    // execute query, etc 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM