apache — php автоматически закрывает TCP-соединение после каждого запроса?

У меня Apache 2.4 / PHP 5.6.13, работающий на Windows Server 2008 R2.

У меня есть API-коннектор, который делает 1 вызов в секунду на пользователя, чтобы прочитать очередь сообщений.

я использую setInterval(...., 1000) сделать ajax-запрос к обработчику, который выполняет фактический вызов API.

Обработчик делает cURL вызывает службу API для чтения очереди сообщений.

Это прекрасно работает для 2 пользователей, но теперь у меня есть 10 пользователей, использующих систему, что означает, что с моего сервера отправляется больше вызовов API.

Многие пользователи, использующие или не использующие API, столкнулись с ошибкой тайм-аута. Когда я смотрю на логи php, я вижу эту фатальную ошибку

[14-Aug-2015 16:37:08 UTC] PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

Я провел исследование по этой проблеме и выяснил, что это не ошибка SQL, а ошибка Windows. Это объясняется здесь.

Мне кажется, что мне нужно отредактировать реестр Windows, чтобы исправить проблему, как она есть объяснил здесь но я не люблю касаться реестра Windows специально на рабочем сервере.

Мой вопрос: поддерживает ли PHP открытое TCP-соединение или закрывает его после каждого запроса?

У меня есть 10 пользователей, использующих «API Caller» и около 200, которые не были. Это только дополнение было 10 пользователей / 10 вызовов API в секунду.

Если предположить, что PHP / cURL автоматически закроет TCP-соединение, то как мне достичь соединения 5000 и только от 10 человек, использующих API?

1

Решение

Проблема заключается в архитектуре вашего приложения. Опрос Ajax не масштабируется.

Короткий опрос (что вы делаете) не масштабируется, потому что он просто наводняет сервер запросами. У вас есть один запрос в секунду и на пользователя. Это дает уже 10 запросов в секунду для 10 пользователей. Вы настроили DoS-атаку на свой сервер!

Длинный опрос (также называемый кометой) означает, что ваш сервер не сразу отвечает на запрос, а ожидает, пока не будет отправлено сообщение, или пока не истечет время ожидания. Это лучше, потому что у вас меньше запросов сейчас. Но это все еще не масштабируемо, потому что на сервере вы будете продолжать забивать базу данных.

WebSockets это то, что вы ищете. Ваш браузер подключается к серверу веб-сокетов и сохраняет соединение навсегда. Это двусторонний канал связи, который всегда доступен для обеих сторон. Есть еще две вещи, которые нужно знать:

  • вам нужен другой сервер для веб-сокетов, Apache не может этого сделать.
  • на стороне сервера вам нужна система событий. Забивать базу данных — это не решение проблемы.

Заглянуть в ratchet как основанный на PHP веб-сокет deamon, и в Autobahn.js для клиентской стороны.

Редактировать: Ratchet к сожалению больше не поддерживается. Я переключился на node.js.

3

Другие решения

Соединения с базой данных PHP используют базовый класс PDO. По умолчанию они закрываются каждый раз, когда запрос завершается (скрипт PHP завершается). Вы можете узнать больше информации, связанной с этим здесь http://php.net/manual/en/pdo.connections.php.

Вы можете заставить ваше соединение с базой данных быть постоянным, что обычно полезно, если вы собираетесь часто использовать соединение с базой данных.

Apache (я предполагаю) похож на другие серверы. Он постоянно прослушивает данный порт для входящих соединений. Он устанавливает, что соединение читает запрос, отправляет ответ и затем закрывает соединение.

Ваша ошибка вызвана тем, что используется много соединений (ОС допускает только столько) ИЛИ переполнение буфера для соединения. Оба они могут быть выведены из вашего сообщения об ошибке.

1

По вопросам рекламы [email protected]