Я пытаюсь заставить PHP сказать Apache закрыть соединение и соответственно освободить рабочий поток. Причина в том, что у меня есть сценарий, который вызывается по запросу клиента и занимает некоторое время для обработки, но ничего не возвращает клиенту, так что просто не имеет смысла держать поток занятым. Код, который я сейчас использую:
ignore_user_abort(true);
header('Content-Length: 0');
flush();
ob_end_flush();
header('Connection: Close');
Так как я отправляю дополнительный асинхронный запрос к этому сценарию из исходного запроса пользователя, Content-Length: 0
не испортит ответ на запрос клиента.
В любом случае, когда я иду, чтобы наблюдать за тем, что делает сервер, я вижу, что есть рабочий поток, занятый долгосрочным запросом, и это именно то, чего я хочу, чтобы не произошло. Я хочу, чтобы скрипт выполнялся в тишине сзади, не занимая потоки Apache. Как я могу это сделать?
Это звучит как плохая практика и много неприятностей, например с параллелизмом и балансировкой нагрузки.
Рассмотрим реализацию очереди задач:
Затем настройте задание демона или cron, которое обрабатывает вышеупомянутую очередь в фоновом режиме вне Apache.
Это дает вам точный контроль над тем, что происходит, когда нет необходимости в подобных взломах. В качестве бонуса вы контролируете использование своего ресурса, контролируя скорость обработки очереди. (Особенно полезно, если вы общаетесь с внешним API, который ограничивает трафик.)
Если вы хотите, чтобы ваша очередь была параллельной, вам ничто не мешает — рассмотрите возможность установки нескольких пулов задач, и каждая задача при создании назначается случайному пулу задач. Затем настройте экземпляр демона для каждого пула задач — нет необходимости в потоках PHP или чем-то подобном.
Других решений пока нет …