2013-04-18 2 views
4

Мы пытаемся внедрить службу уведомлений на длинных опросах в ERP нашей компании. Подобно уведомлениям Facebook.Длинный опрос с Ajax и PHP - Apache freezes

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

  • РНР с 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 после перезагрузки. Вы не представляете, что делать.

+1

Хотя это и не так, но существует [ограничение на максимальное постоянное соединение на сервер] (http://stackoverflow.com/a/985704/570812), реализованных в различных браузерах. Возможно, вам захочется проверить, будет ли на 4-й вкладке подключаться любое количество сотрудников. – Passerby

+0

Не спать страницы, которые блокируют поток apache/php. Вам нужно будет увеличить число ваших работников Apache и т. Д. Все, что дерьмо. В моей платформе CRM я делаю это с простым текстовым файлом, просматриваемым для каждого пользователя. Временная отметка последней проверки против отметки времени теперь, если разница> 60, тогда делать опрос иначе ничего не делать. Установите скрипт для запуска каждую секунду. – Dave

+0

Попробуйте использовать websocks для этого, над python. –

ответ

4

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

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

Давайте предположим, что я получал AJAX данные из

http://domain.com/ajax 

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

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

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

Для получения дополнительной информации посетите this thread.

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

Если вы хотите узнать больше о заголовках, ознакомьтесь с ними here on StackOverflow и here on Mozilla Developer's page. Благодаря!

+2

Вы говорите в стороне от ограничения браузера на соединение, длительный опрос работает нормально на вашем сервере Apache? –

2

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

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

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

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

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

+1

При разработке службы уведомлений я пробовал много вещей. Я также сделал что-то похожее на то, что вы предложили. Превращается вся идея, когда вы пытаетесь поддерживать сотни (или более) соединений за один раз - вы просто убьете сервер. Я нашел лучшее решение, хотя - Node.js с Socket.io в качестве протокола подключения. Я знаю, что для изучения новых технологий требуется некоторое время, но это того стоит. Это того стоит, так что я провел половину года, описывая это в своем тесте «Основы информатики» :). Вы должны попробовать! Повеселись! – ex3v

Смежные вопросы