我设计了一个编码平台,就像Spoj和Codeforce一样,将在我的学院局域网上组织竞赛。
我在那里使用了长轮询,以便通过JavaScript警报消息向所有用户广播来自Admin的任何通知。当论坛上发布任何内容时,管理员也会收到通知。
但是,只有16个用户(包括1管理员)访问该站点,服务器显示的是too many sql connections。我重新启动了我的笔记本电脑(服务器),它继续了一段时间,然后又崩溃了;给出了和以前一样的错误信息。
当我删除这两个长投票过程时,一切都顺利地进行着。
用于长轮询的服务器端代码:
include 'dbconnect.php';
$old_ann_id = $_GET['old_ann_id'];
$resultann = mysqli_query($con,"SELECT cmntid FROM announcements ORDER BY cmntid DESC LIMIT 1");
while($rowann = mysqli_fetch_array($resultann)){
$last_ann_id = $rowann['cmntid'];
}
while($last_ann_id <= $old_ann_id){
usleep(10000000);
clearstatcache();
$resultann = mysqli_query($con,"SELECT cmntid FROM announcements ORDER BY cmntid DESC LIMIT 1");
while($rowann = mysqli_fetch_array($resultann)){
$last_ann_id = $rowann['cmntid'];
}
}
$response = array();
$response['msg'] = 'new';
$response['old_ann_id'] = $last_ann_id;
$resultann = mysqli_query($con, "Select announcements from announcements where cmntid = $last_ann_id");
while($rowann = mysqli_fetch_array($resultann)){
$response['announcement'] = $rowann['announcements'];
}
echo json_encode($response);发布于 2014-01-27 09:20:15
定义了最大连接。假设默认为100或151个连接,这取决于MySQL的版本。您可以在phpmyadmin中的“服务器变量和设置”中看到值(或者直接执行*显示变量,如"max_connections";* )。
如果将其设置为非常低的值(例如10),并且您有(比方说)15个用户,那么您将很快达到极限。您将为每个长轮询脚本提供自己的连接,并且该连接可能处于打开状态,直到该长轮询脚本结束。每次检查数据库后,脚本可能会断开连接,然后在下次检查时重新连接(也就是说,如果您的长轮询脚本每5秒检查一次数据库,您可能有4.5秒以上的时间,当前有到数据库的连接,但没有使用连接)。
但是,您可以拥有更多的连接,但是如果每个用户多次触发ajax轮询,每个用户都可以有几个同时进行的连接。这可能很容易用javascript中的一个小错误来完成。
更糟糕的是,如果使用的是持久连接,则在用户离开调用长轮询脚本的页面后,可能会打开连接。
编辑-基于您的脚本更新。
注意:我不确定您的dbconnect.php包括做什么。我可能很容易在其中调用一个连接/断开函数,但我只是将它作为使用mysqlu_close和mysqli_connect函数的代码放在了这个示例代码中。
<?php
include 'dbconnect.php';
$old_ann_id = $_GET['old_ann_id'];
$resultann = mysqli_query($con,"SELECT MAX(cmntid) FROM announcements");
if($rowann = mysqli_fetch_array($resultann))
{
$last_ann_id = $rowann['cmntid'];
}
$timeout = 0;
while($last_ann_id <=$old_ann_id and $timeout < 6)
{
$timeout++;
mysqli_close($con);
usleep(10000000);
clearstatcache();
$con = mysqli_connect("myhost","myuser","mypassw","mybd");
$resultann = mysqli_query($con,"SELECT MAX(cmntid) FROM announcements");
if($rowann = mysqli_fetch_array($resultann))
{
$last_ann_id = $rowann['cmntid'];
}
}
if ($last_ann_id >$old_ann_id)
{
$response = array();
$response['msg'] = 'new';
$response['old_ann_id'] = $last_ann_id;
$resultann=mysqli_query($con,"SELECT cmntid, announcements FROM announcements WHERE cmntid>$old_ann_id ORDER BY cmntid");
while($rowann = mysqli_fetch_array($resultann))
{
$response['announcement'][]=$rowann['announcements'];
$response['old_ann_id'] = $rowann['cmntid'];
}
mysqli_close($con);
echo json_encode($response);
}
else
{
echo "No annoucements - resubmit";
}
?>我在主循环中增加了一个计数。但是一旦它执行了6次,它就会退出循环,是否找到任何东西。这样,即使有人离开页面,脚本也只会运行一段很短的时间(最多一分钟)。您必须修改javascript才能捕捉到这一点,并重新提交ajax调用。
另外,我已经将响应中的声明更改为数组。这样,如果在脚本运行时有几个公告,所有这些都会被带回。
https://stackoverflow.com/questions/21327714
复制相似问题