使用 JQuery、PHP 和 MySQL 为实时统计页面优化多个连续的 ajax 调用

Posted

技术标签:

【中文标题】使用 JQuery、PHP 和 MySQL 为实时统计页面优化多个连续的 ajax 调用【英文标题】:Optimizing multiple successive ajax calls with JQuery, PHP, and MySQL for a real-time stats page 【发布时间】:2012-11-20 10:21:12 【问题描述】:

我有一个 php 脚本,它显示了通过 JQuery AJAX 调用为锦标赛评分网站加载的多个数据表。这些表格是实时计算的个人和团队得分。

每分钟检查一次每个表的新分数,并在需要时刷新。为此,每个表都会向上次更新分数的时间发送一个快速 ajax 请求...如果时间与表当前的时间不同,则用新数据刷新表。

我的问题是,这些锦标赛可能会变得非常大,有很多参与者、团队、部门和分数,并且加载每个表会使用服务器资源。如果少数人正在查看实时统计数据,这没有问题,但是一旦超过 50 人连接到此统计数据页面,服务器就会开始严重滞后。

我想知道我可以做些什么来优化数据、ajax 调用或服务器本身以尽可能高效地运行,这样服务器就不会那么快达到极限。我已经梳理了 mysql 调用,并尝试尽可能优化所有内容,但似乎还不够。

任何想法将不胜感激!

【问题讨论】:

【参考方案1】:

您可以使用缓存,例如在您的架构中 memcache 非常适合。每次您的服务器收到请求时,您的 php 应用程序都会尝试从缓存中获取结果,如果未找到则执行查询。

现在你可以选择两种不同的方式:

简单,等待缓存过期时间。当缓存过期时,服务器会错过搜索并提交新的查询。这通常是短期缓存(秒或分钟) 硬,缓存在很远的将来到期,例如几小时甚至几天)。在这种情况下,您的应用程序会在每次更新数据库时刷新缓存内容。在这种情况下,很明显,几乎所有请求都命中了缓存(最佳性能)。

这个例子,基于简单的方法,缓存键直接基于提交的SQL。

global $memcache;
$memcache = new Memcache;

// Gets key / value pair into memcache ... called by mysql_query_cache()
function getCache($key) 
    global $memcache;
    return ($memcache) ? $memcache->get($key) : false;


// Puts key / value pair into memcache ... called by mysql_query_cache()
function setCache($key,$object,$timeout = 60) 
    global $memcache;
    return ($memcache) ? $memcache->set($key,$object,MEMCACHE_COMPRESSED,$timeout) : false;


// Caching version of mysql_query()
function mysql_query_cache($sql,$linkIdentifier = false,$timeout = 60) 
    if (($cache = getCache(md5("mysql_query" . $sql))) !== false) 
        $cache = false;
        $r = ($linkIdentifier !== false) ? mysql_query($sql,$linkIdentifier) : mysql_query($sql);
        if (is_resource($r) && (($rows = mysql_num_rows($r)) !== 0)) 
            for ($i=0;$i<$rows;$i++) 
                $fields = mysql_num_fields($r);
                $row = mysql_fetch_array($r);
                for ($j=0;$j<$fields;$j++) 
                    if ($i === 0) 
                        $columns[$j] = mysql_field_name($r,$j);
                    
                    $cache[$i][$columns[$j]] = $row[$j];
                
            
            if (!setCache(md5("mysql_query" . $sql),$cache,$timeout)) 
                // If we get here, there isn't a memcache daemon running or responding
            
        
    
    return $cache;

【讨论】:

【参考方案2】:

缓存输出,每 1 或 5 分钟刷新一次缓存...

所以我的意思是,只需将数据库输出写入文件,然后在那一分钟内的所有请求都使用该文件...每个请求,检查文件的年龄,如果早于 1 或 2 或 5(示例)分钟,删除缓存文件并重建它

这将允许 mysql 在那段时间休息...... Ajax 调用正是需要做的......只要你觉得你的间隔是必要的

一些示例 PHP:

$cache_expires = 2; # Minutes
if (file_exists("stats.cache") && filemtime("stats.cache")>time()-$cache_expires*60) 
  # Read cache
  $result = unserialize(file_get_contents("stats.cache"));
  # Display result
 else 
  # Query the database
  $result = get_stats_from_database();
  # Write cache
  file_put_contents("stats.cache",serialize($result));
  # Display result

【讨论】:

听起来是个好主意,但由于有许多这样的数据库输出要缓存(每页加载超过 10 个),您是否认为每隔几分钟创建和删除这些缓存文件会还会导致服务器负载过重吗?也许将它们缓存在新的数据库表中而不是物理文件中会更好……你怎么看?

以上是关于使用 JQuery、PHP 和 MySQL 为实时统计页面优化多个连续的 ajax 调用的主要内容,如果未能解决你的问题,请参考以下文章

实时更新 MySQL 数据

实时聊天、消息处理 - Socket.io、PHP、MySQL、Apache

使用 php 和 jquery 实时通知

将jquery mobile和php mysql转换为apk文件

AJAX 实时电子邮件验证 (PHP)

使用Jquery和PHP单击保存按钮时如何将多个表行更新为mysql表?