Назад | Перейти на главную страницу

PHP - работает ли curl в моей системе асинхронно?

Я создаю веб-приложение. У меня есть база данных книг, проиндексированных в ElasticSearch и REST API, написанных на PHP.

В приложении есть поле поиска, в котором я набираю имя книги, и JS-скрипт вызывает поисковый запрос, который затем выполняет curl-запрос с поисковым запросом к ElasticSearch.

Проблема в том, что когда пользователь вводит быстро, запросов слишком много. Он начинает замедляться, и хотя обычно один запрос длится около 200 мс, он увеличивается до 5-10 с, что слишком долго. Я мог бы выполнять меньше запросов, но мне нужна мгновенная обратная связь.

Поэтому я спрашиваю - это то, что само ядро ​​curl на моем сервере выполняет только один запрос за раз, даже если они вызываются в отдельных запросах PHP, или это что-то еще?

Короткий ответ: нет, это не асинхронно. Более длинный ответ: «Нет, если только вы сами не написали для этого бэкэнд».

Если вы используете XHR, каждый запрос будет иметь другой рабочий поток на бэкэнде, что означает, что ни один запрос не должен блокировать другие, запрещая выполнение ограничений процесса и памяти. Хотя XHR представляет интерфейс, основанный на событиях, это все еще живой HTTP-запрос, синхронно обрабатываемый браузером (вы получаете только 1 поток в js). Бэкэнд php также синхронно выполняет вызовы curl, не возвращая результаты для вашего HTTP-запроса XHR, пока вызов curl не завершится. Теперь вы можете настроить свой javascript для опроса результатов, но, поскольку ваше время жизни составляет <3-5 секунд, это того не стоит.

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

На самом деле, ваш клиентский javascript должен ждать, чтобы выполнить следующий поиск, пока последний поиск не вернется. С обратной стороны, чтобы предотвратить DOS, если один клиент начинает отправлять вам слишком много запросов на поиск завершения, начните отбрасывать запросы с помощью HTTP 429 и обрабатывать 429 ответов в своем JS, чтобы выполнить инкрементную отсрочку и повторить попытку позже, если это необходимо.

Еще одна вещь, которую вам обязательно нужно сделать, - это установить для таймаута запроса в curl что-то намного меньшее, чтобы время ожидания истекло соответствующим образом. Если данные поиска полезны только в течение 2-3 секунд, время ожидания запроса curl должно быть примерно таким же. Если ваш бэкэнд достаточно умен, он будет интерпретировать закрытое соединение как означающее «прекратить поиск», и, надеюсь, вы остановите потерю ресурсов вовремя, чтобы другой процесс мог их использовать.

Насколько я понимаю, у вас есть веб-сервер, на котором запускается какой-то скрипт, который можно использовать для автозаполнения. Этот скрипт выполняет запрос к другому серверу с помощью cURL.

Во-первых, чтобы ответить на ваш вопрос: ваш веб-сервер, по всей вероятности, может запускать несколько процессов PHP параллельно, и поскольку cURL вызывается PHP, он тоже будет работать параллельно. Вы не сказали, какой веб-сервер у вас запущен, но большинство поддерживает это.

Однако похоже, что ваша установка требует значительных сетевых ресурсов: каждое нажатие клавиши генерирует запрос к вашему серверу, который генерирует запрос к другому серверу. Если либо вашему серверу не хватает ресурсов, либо на другом сервере установлен ограничитель скорости, вы получите плохую производительность. Возможно, кешируйте результаты на своем веб-сервере (чтобы вам не приходилось так часто использовать cURL) или заставьте Javascript ждать несколько миллисекунд, чтобы люди не запускали слишком много запросов.