5

我有以下 PHP 脚本,它基本上连接到 MongoDB,写入一个文档,然后关闭连接 19000 次:

<?php
for($i=0; $i < 19000; $i++) {
    $con = new Mongo("mongodb://localhost:27017");
    $db = $con->selectDB('test');

    $col = $db->selectCollection('close_wait_test');
    $col->insert(array('Test' => 'Value1'));

    $con->close();
}
?>

运行此脚本一次可以正常工作,但如果我在几秒钟后运行脚本,我会收到“无法分配请求的地址”异常,这是可以理解的,因为服务器系统可能会用完端口。

但是,如果我删除 $con->close(); 我可以一遍又一遍地运行该脚本,而不会对数据库造成任何明显的压力。我假设这是因为与数据库的连接是持久的,并且在脚本上重用了相同的初始连接。

我想知道的是,如果 20k+ 个不同的用户同时运行 1 个该脚本循环,数据库会发生什么情况?例如,是否会因为每个用户需要创建一个到数据库的连接而简单地用完可用连接?还是所有这些用户都使用第一个用户创建的相同初始连接?

4

2 回答 2

5

您不应该在每次迭代时调用 ->close() 。如果您调用 close,则告诉驱动程序不要重用持久连接。如果你在一个紧密的循环中运行它,那么操作系统会用完端口来使用,因为它们都处于 TIME_WAIT 状态。

PHP 驱动程序使用持久连接,如果(不调用 ->close)您像示例中那样在紧密循环中运行“new Mongo”,驱动程序将不会建立新连接并重用已经存在的连接。

于 2012-04-16T13:50:59.373 回答
0

你会得到一个致命的错误:

PHP Fatal error: Uncaught exception 'MongoConnectionException' with message 'Cannot assign requested address' in /home/pierre/test.php:3 Stack trace: #0 /root/test.php(3): Mongo->__construct('mongodb://local...') #1 {main} thrown in /home/pierre/test.php on line 3

c=0; while [ $c -le 20000 ]; do php test.php; c=$[c+1]; done

带有 mongodb 和默认配置的 Testet。MongoDB 继续运行,其他脚本继续工作。也许您应该考虑使用诸如作业服务器之类的东西,例如 gearman。

于 2012-04-16T12:42:51.170 回答