У меня есть следующий скрипт 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(); } ?>
Запуск этого сценария один раз отлично работает, но если я запустил скрипт несколько секунд спустя, я получаю исключение «Не могу назначить запрошенный адрес», что понятно, поскольку серверная система, вероятно, закончилась из портов.
Если, однако, я удаляю $ conc> close (); Я могу запускать этот сценарий снова и снова без каких-либо заметных нагрузок в базе данных. Я предполагаю, что это связано с тем, что соединение с базой данных является постоянным и повторяет одно и то же начальное соединение в скрипте.
Я хотел бы знать, может ли 20k + разные пользователи запускать 1 цикл этого скрипта одновременно, что произойдет с базой данных? например, доступные соединения просто закончились, потому что каждый пользователь должен создать одно соединение с базой данных? или все эти пользователи будут использовать одно и то же начальное соединение, созданное первым пользователем?
Вы не должны вызывать -> close () на каждой итерации. Если вы вызовете близко, вы сообщите драйверу, чтобы он не повторно использовал постоянное соединение. Если вы запускаете это в узком цикле, то для ОС используется неиспользуемые порты, поскольку они все находятся в состоянии TIME_WAIT.
Драйвер PHP использует постоянные соединения, и если (без вызова -> закрыть) вы запускаете «новый Mongo» в узком цикле, как в вашем примере, драйвер не будет создавать новые подключения и повторно использовать уже существующий.
Вы получите фатальную ошибку:
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
Testet с конфигурацией mongodb и по умолчанию. MongoDB продолжает работать, а другие скрипты продолжают выполнять свою работу. Может быть, вам стоит подумать о том, чтобы использовать что-то вроде сервера заданий, например, редуктора.