Длительный опрос с Ajax и PHP – Apache замерзает

Мы пытаемся внедрить службу уведомлений на основе долгого опроса в ERP нашей компании. Подобно уведомлениям Facebook.

Используемые технологии:

  • PHP с timeout установленным на 60 секунд и 1 секундой sleep в каждой итерации цикла.
  • jQuery для обработки AJAX.
  • Apache как веб-сервер.

После почти месяца кодирования мы пошли на производство. Через несколько минут после развертывания нам пришлось откатить все. Оказалось, что наш сервер (8 ядер) не может обрабатывать длинные запросы от 20 сотрудников, используя каждую вкладку 5 браузеров. Например: Пользователь открыл 3 вкладки с нашей ERP, с одним длинным опросом AJAX на каждой вкладке. Открытие 4-й вкладки невозможно – она ​​зависает, пока не будет убит один из предыдущих 3 (и, следовательно, AJAX остановлен).

«Ограничения Apache», подумали мы. Итак, мы пошли гуглингом. Я нашел некоторую информацию об модулях и конфигурациях MPM Apache, поэтому я попробовал. Наш сервер использует prefork MPM, так как apachectl -l показал нам. Поэтому я изменил несколько строк в конфиге, чтобы выглядеть примерно так:

 <IfModule mpm_prefork_module> StartServers 1 MinSpareServers 16 MaxSpareServers 32 ServerLimit 50% MaxClients 150 MaxClients 50% MaxRequestsPerChild 0 </IfModule> 

Смешно, это работает на моей локальной машине с аналогичной конфигурацией. На сервере похоже, что Apache игнорирует конфигурацию, потому что с установкой MinSpareServers на 16 она запускает 8 после перезагрузки. Вы не представляете, что делать.

Passerby в первом комментарии предыдущего сообщения дал мне хорошее направление, чтобы проверить, ударим ли мы максимальные соединения браузера с одним сервером.

Как оказалось, каждый браузер имеет эти ограничения, и вы не можете их изменить (насколько я знаю). Мы сделали обходной путь, чтобы заставить его работать.

Предположим, что я получаю данные AJAX от

 http://domain.com/ajax 

Чтобы избежать ударов по максимальным соединениям с браузером, каждый длинный опрос AJAX подключается к случайному субдомену, например:

 http://31289.domain.com/ajax http://43289.domain.com/ajax 

и так далее. На DNS-сервере есть подстановочный знак, указывающий от *.domain.com на *.domain.com , а поддомен – это уникальное случайное число, созданное JS на каждой вкладке.

Для получения дополнительной информации ознакомьтесь с этой веткой .

Также возникли некоторые проблемы с AJAX Same Origin Security , но нам удалось разобраться с ними, используя соответствующие заголовки как на стороне JS и на PHP .

Если вы хотите узнать больше о заголовках, посмотрите здесь, на StackOverflow , и на странице разработчика Mozilla . Благодаря!

Я успешно реализовал настройку LAMP с длинным опросом. Две вещи, о которых следует помнить, часы внутреннего исполнения php для linux не изменяются и не увеличиваются функцией «usleep ()». Поэтому установка максимального времени выполнения потребуется только для случаев редких краев, когда получение данных занимает больше времени, чем обычно, или, возможно, для установки окон. Кроме того, при длительном опросе в виду, что, пройдя более 20 секунд, вы уязвимы для того, чтобы иметь тайм-аут браузера.

Во-вторых, вам нужно будет убедиться, что ваши сеансы не блокируются (если сеансы используются).

У Apache действительно не должно быть проблем с тем, что вы хотите сделать. Хотя, я буду признавать, что веб-серверы, такие как nginx или веб-сервер, ориентированный на ajax, могут лучше обрабатывать параллельные соединения. Если вы можете опубликовать свой код для обработчика ajax, мы сможем выяснить, в чем проблема.

Используя субдомены или другие потоки, предлагаемые – несколько веб-серверов на отдельных портах, помните, что вы можете столкнуться с проблемами безопасности домена JavaScript.

Я говорю: не изменяйте конфигурацию apache, пока не столкнетесь с проблемой и не исчерпали все остальные параметры; будьте осторожны с сеансами PHP и убедитесь, что AJAX ожидает ответа, перед отправкой другого запроса;)