Золотые сигналы SRE для веб-сервера
Где бы мы были без веб-серверов? Вероятно, без интернета вообще ...
В наши дни простой веб-сервер имеет две основные функции: обслуживание простого статического содержимого, такого как HTML, JS, CSS, изображения и т.д., и передачу динамических запросов в бэкэнд приложения, например, PHP, Java, PERL, C, COBOL и т.д. Таким образом, веб-сервер обслуживает большинство наших критически важных сервисов, включая динамический веб-контент, API-интерфейсы и всевозможные специализированные сервисы, даже базы данных, поскольку в наши дни всё, кажется, общается по HTTP.
Поэтому получать хорошие показатели работы (сигналы) для веб-серверов - критично.
К сожалению, сами серверы не измеряют и не сообщают эти данные очень хорошо, и совсем не в агрегации с другими данными (по крайней мере, бесплатно). Таким образом, у нас остается три варианта:
- Использовать очень ограниченные встроенные отчеты о состоянии или страницы о состоянии.
- Собирать и агрегировать логи HTTP веб-сервера для этих важных данных.
- Использовать показатели вышестоящих балансировщиков нагрузки (LB), если есть такая возможность.
Последний вариант - использовать метрики для каждого внутреннего сервера LB обычно является наилучшим способом, и в приведенном выше разделе «Золотые сигналы SRE балансировщиков нагрузки» подробно описано, как это сделать.
Однако не все системы имеют правильный тип LB, и не все системы мониторинга поддерживают получение данных такого типа бэкэнда - например, это довольно сложно в Zabbix, так как он пытается получить данные об одном хосте (веб-сервере) от другого хоста (LB). И AWS ELB/ALB также имеют ограниченные данные.
Поэтому, если следует обратить внимание на страницы состояния веб-сервера и журналы HTTP, ниже приведены несколько болезненных, но стоящих способов.
Подготовка к сбору метрик веб-сервера
Есть несколько вещей, которые должны быть готовы, чтобы получить информацию о журналах и статусе:
Включить мониторинг состояния
Необходимо включить мониторинг состояния. Как для Apache, так и для Nginx лучше всего обслуживать его через другой порт (например, 81) или ограничить его для локальной сети, систем мониторинга и т.д., чтобы злоумышленники не могли получить к нему доступ.
- Apache - Включить mod_status, включая ExtendedStatus. См. руководство DataDog по Apache от DataDog.
- Nginx - включить модуль stub_status_module. См. руководство DataDog по Nginx.
Включить журналирование
Нам нужны журналы, а это значит, что нужно их настроить, поместить в удобное место и в идеале разделить их с помощью vhost.
Нам нужно получить время отклика для журналов, что, к сожалению, не является частью стандартного формата или формата по умолчанию. Следует отредактировать веб-конфиги, чтобы получить это:
- Apache - нам нужно добавить поле «%D» в формат журнала (обычно в конце), которое будет отображать время ответа в микросекундах (используйте %T на Apache V1.x, но он получает только секунды).
Это базовый эквивалент Nginx $request_time, приведенный ниже. Обратите внимание, что существует неподдерживаемый модуль mod-log-firstbyte, который приближается к Nginx $upstream_time, который действительно измеряет время ответа серверной части. См. Документацию журнала Apache. - Nginx - нам нужно добавить поле «$upstream_response_time» для времени ответа серверной части, обычно в конце строки журнала. Использование этого «внутреннего времени» позволяет избежать длительного времени для систем, которые отправляют большие ответы более медленным клиентам.
- Nginx также поддерживает поле «$request_time» в определении журнала. Это время до тех пор, пока последний байт не будет отправлен клиенту, поэтому он может захватывать большие ответы и/или медленных клиентов.
Это может быть более точной картиной взаимодействия с пользователем (не всегда), но может быть слишком шумным, если большинство ваших проблем связано с системой, а не с клиентом. См. Документацию журнала Nginx.
Обратите внимание, что многие люди также добавляют в журнал заголовок X-Forwarded-For. Если это или другие поля присутствуют, вам может потребоваться настроить инструменты синтаксического анализа, чтобы получить правильное поле.
Обработка журналов для метрик
Как будет видно ниже, наиболее важные сигналы веб-сервера, особенно о задержках, можно получить только из журналов, которые трудно читать, анализировать и резюмировать. Но это следует делать.
Существует множество инструментов для чтения журналов HTTP, хотя и большинство из них ориентированы на создание данных веб-сайтов, пользовательский трафик, анализ URL-адресов и т.д. У нас другой фокус, чтобы получить золотые сигналы - поэтому сначала нам нужен набор инструментов, которые могут надежно читать, анализировать и резюмировать журналы таким образом, чтобы мы могли использовать их в наших системах мониторинга.
У вас вполне могут быть свои любимые инструменты в этой области, такие как постоянно присутствующий стек ELK, который может сделать это с небольшой работой (как Splunk, Sumologic, Logs и т. Д.). Кроме того, большинство инструментов мониторинга SaaS, таких как DataDog, может извлекать эти метрики с помощью своих агентов или поддерживаемых сторонних инструментов.
Для более традиционных систем мониторинга, таких как Zabbix, это является более сложной задачей, поскольку они не являются хорошими встроенными программами чтения журналов или процессорами. К тому же нас не очень интересуют сами строки логов. Вместо этого нам нужны агрегированные данные о задержке и частоте ошибок по времени в журналах, что противоречит многим другим целям «журналирования».
Итак, если ваша система мониторинга изначально поддерживает показатели журнала веб-сервера, все готово, и смотрите ниже. В противном случае для вашей системы могут быть сторонние инструменты или инструменты с открытым исходным кодом, и все готово, см. ниже.
Если у вас нет существующей системы мониторинга или стороннего инструмента/инструмента с открытым исходным кодом для этого, вам несколько не повезло, поскольку мы не можем найти готовое решение, особенно для получения этих данных в 1 или наиболее полезные для нас 5-минутные блоки.
Реальность такова, что синтаксический анализ и агрегация журналов сложнее, чем кажется, и очень мало инструментов, которые могут сделать это на сервере, чтобы обеспечить мониторинг на основе агентов. Кажется, что инструмент GoAccess может кое-что из этого, с выводом CSV, который вы можете проанализировать. В остальном существует множество хороших сценариев awk и PERL, но мало таких, которые поддерживают скользящее временное окно или даже смену журнала.
Вам нужно найти систему, инструмент или службу для извлечения показателей из веб-журналов.
Сопоставляя наши сигналы с веб-серверами, мы получаем:
- Частота запросов (Request Rate) - запросов в секунду, которую вы можете получить трудным путем, прочитав журналы доступа и строки подсчета, чтобы получить общее количество запросов, и выполнить дельту, чтобы получить количество запросов в секунду. Или простой способ, используя информацию о статусе сервера, и таким образом:
- Apache - использовать общее количество доступов, которое является счетчиком общего количества запросов за время существования процесса. Выполните дельта-обработку для получения запросов/сек. НЕ используйте «Запросы в секунду», которые действуют в течение всего срока службы сервера и, следовательно, бесполезны.
- Nginx - Use Requests, который является счетчиком общего количества запросов. Выполните дельта-обработку для получения запросов/сек.
- Частота ошибок (Error Rate ) - это должно быть получено из журналов, где ваши инструменты должны подсчитывать 5хх ошибок в секунду, чтобы получить частоту. Вы также можете насчитать 4хх ошибок, но они могут быть шумными и обычно не вызывают ошибок с точки зрения пользователя. Вам действительно нужно быть чувствительным к ошибкам 5xx, которые напрямую влияют на пользователя и всегда должны быть нулевыми.
- Задержка (Latency) - это должно происходить из журналов, где ваши инструменты должны агрегировать время запроса или ответа, которое вы добавили в журналы выше. Как правило, вы хотите получить среднее (или, что еще лучше, медианное значение) времени ответа за период выборки, например 1 или 5 минут.
Как упоминалось выше, вам понадобятся подходящие инструменты для этого, так как нет ни полезного скрипта, ни инструмента, чтобы сделать это обычным образом. Обычно вам нужно отправлять журналы в службу, подобную ELK (ELK, Sumo, Logs и т. Д.), в систему мониторинга (DataDog и т.д.) или в систему APM, такую как New Relic, App Dynamics или DynaTrace. - Насыщенность (Saturation) - это сложная область, которая различается в зависимости от веб-сервера:
- Nginx - практически невозможно загрузить сам сервер Nginx, если ваши рабочие и максимальное количество подключений установлены достаточно высокими (по умолчанию 1x1K, обычно следует устанавливать намного больше, мы используем 4x2048K).
- Apache - большинство людей работают в режиме pre-fork, поэтому на каждое соединение приходится один процесс Apache с практическим пределом в 500 или около того. Таким образом, с медленным сервером очень легко насытить сам Apache. Таким образом: Контролируйте BusyWorkers по сравнению с наименьшим из настроенных вами MaxRequestWorkers/MaxClients/ServerLimit. Когда Busy = Max, этот сервер переполнен и не может принимать новые соединения (новые соединения будут помещены в очередь).
Вы также можете подсчитать ошибки HTTP 503 из журналов, которые обычно возникают при перегрузке внутреннего сервера приложений, хотя в идеале вы можете получить эти данные непосредственно с сервера приложений.
Для многих систем Apache критически важно измерить память как ресурс, потому что это, безусловно, самый простой способ убить систему на основе Apache, исчерпать оперативную память, особенно если вы используете modPHP или другой сервер приложений на основе модов.
- Утилизация (Utilization) - для Nginx это редко актуально, но для Apache это то же самое, что и для насыщенности (соотношение BusyWorkers и наименьшего из настроенных MaxRequestWorkers/Max Clients/Server Limit).