Еще в процессе первого нагрузочного тестирования Битрикса версии 6.0 коллеги из QSoft столкнулись с ситуацией, о которой сегодня хочу написать. На тот момент она не была детально изучена, но на последнем тестировании версии 9.5, которое проводилось совместно с компанией Онтико, стали понятны симптомы проблемы и последствия. В финальном отчете проблема описана на 19 странице под заголовком "Особенности генерации тестовой нагрузки", хочу сейчас подробно остановиться на том, как это было.[spoiler]Команда Онтико во главе с Олегом Буниным осуществляла нагрузочное тестирование на мощностях masterhost, мы со своей стороны курировали процесс чтобы продукт работал правильно. В какой-то момент коллеги из Онтико объявили о том, что нашли технологический предел работы Битрикса.
Сервер отдавал порядка 100 страниц в секунду (более 8 000 000 хитов в сутки), возможно, в другой ситуации удовлетворились этим результатом. Но поскольку с нашей стороны вопросом занимался Игорь Усольцев, а он человек с большим пониманием, следующее, на что он обратил внимание, это то, что нагрузка на сервере упала.
Выглядит это так: открываем top, при сортировке по CPU сверху нет ни httpd, ни mysql, load average стремительно падает. В базе не висит ни одного запроса. При этом тестовая нагрузка не останавливается, но Apache не отвечает, клиенты отваливаются по таймауту.
Вот что происходит с графиком: число отдаваемых страниц падает (коричневый), а время отдачи стремительно возрастает (розовый).
При 100 запросах в секунду сервер работал, затем пошло увеличение нагрузки и скопилось огромное число полуоткрытых соединений на Apache:
# netstat -an|grep SYN_SENT|wc -l 865
При нормальной работе Apache число соединений в статусе SYN_SENT будет минимально. Даже на сильно загруженном проекте сложно получить значение больше 10. Т.е. нагрузочное тестирование перешло в эффективную DOS атаку, которая положила Apache.
Обратите внимание на график: он похож на седло. Когда Игорь получил его, он в шутку так и назвал увиденное: "седло бунина" Этот термин прижился внутри компании, и когда теперь мы сталкиваемся с подобной ситуацией на крупных проектах (даже на своем сайте), так и говорим: "ну вот, седло бунина".
Что с этим делать?
Перезапуск Apache решает проблему. Это, конечно, можно использовать в скриптах мониторинга, но это костыль.
Должен сказать, что магического параметра чтобы просто закрыть вопрос мы не нашли. Исследование этого вопроса дало определенную информацию:
проблема характерна для linux, на FreeBSD с версии 6 она не наблюдается;
apache может подняться сам если сбросить нагрузку;
момент появления проблемы зависит от частоты процессора: после определенного момента сервер не успевает эффективно обслуживать новые соединения;
разные люди сталкивались с такой ситуацией, но учитывая, что возникает не часто, просто рестартуют веб сервер;
apache имеет параметр настройки TCP_DEFER_ACCEPT, влияющий на работу TCP, но во второй версии Apache он уже имеет оптимальное значение (т.е. на первой версии, вероятно, проблема будет появляться чаще);
ограничения на файерволе будут препятствовать нормальной работе сайта.
Исходя из перечисленного появились методы борьбы. Один вариант: поставить на одну машину два Apache за одним nginx. Число child'ов Apache надо соответственно уменьшить (например, был один Apache с MaxClients 10, делаем 2 по 5). Это позволяет увеличить порог устойчивости.
Другой вариант - сделать веб кластер на нескольких веб серверах. Это то, что мы сделали на своем сайте. Проблема ушла, а кроме того упала нагрузка на диски, и, как следствие, сайт стал работать стабильнее.
Коллеги, кто из вас сталкивался с такой ситуацией, как-то удавалось решить другими способами?
Если отловить данную ситуацию на странице мониторинга апача /server-status, мы увидим, что слоты забиты со статусом "...reading...". В принципе еще как рецепт можно попробовать ловить это (если пробьетесь к апачу мониторингом), грепить, и рестартовать апач.
Мы натыкались на нечто подобное в своей практике. Правда там это были вин2003 и сиквел сервер 2005. Терминальный сервер, на котором работает клиентское приложение, обращается к серверу БД. При увеличении количества экземпляров клиентского приложения появлялись тормоза, которые не проявлялись ни в расходе памяти, ни в дисковом ИО, ни в расходе ЦПУ. Дело оказалось в недостатке числа TCP портов, на которых устанавливались исходящие соединения с сиквел-сервером. Дело в том, что вин2003 по умолчанию имеет верхнюю границу выделения портов MaxUserPort = 5000 и таймаут удержания порта в TIME_WAIT состоянии TcpTimedWaitDelay = 240. В итоге приложение просто ждало пока освободится порт, чтобы можно было создать исходящее подключение. Проблему решили установив верхнюю границу доступных портов в 60000 и уменьшив таймаут до 30 секунд. Подробнее - здесь: и здесь: Возможно, в вашем случае тоже есть подобные ограничения, которые обходятся изменением настроек ОС (я не силен в никсах, поэтому ничего более конкретного подсказать не смогу).
Тоже видится проблема в настройках сетевой инфраструктуры.При подготовке VMBitrix3 проведем ряд тестов и составим рекомендации по более тонкой настройки ОС.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».