Привет! Меня зовут Андрей, я возглавляю команду, которая отвечает за надежность и стабильную работу бэкенда в Wrike. Если вы когда-нибудь задумывались, что же такое «backend reliability», то знайте, что вы не один! Я часто объясняю, что это что-то вроде должности инженера по надежности сайта (SRE), но сфокусированная исключительно на бэкенде. В статье я расскажу о зонах ответственности BRE команды и инструментах, которые мы применяем для поддержания стабильной работы бэкенда на высоком уровне.

За что отвечает BRE команда

Backend reliability engineer (BRE) — это специалист, который отвечает за устойчивость, стабильность, масштабируемость и производительность серверной части приложения. Это человек, который первым приходит на помощь при возникновении проблем с доступностью или стабильной работой бэкенда. Мы не добавляем в продукт новые функциональности, которые видят пользователи, но если мы не справимся со своими задачами, и приложение не выдержит нагрузку, то пользователи это обязательно заметят.

Для бэкенд-инженеров мы предоставляем оптимизированные и надежные решения, которые можно интегрировать в процесс написания кода. Примером таких общих решений являются библиотеки работы с базой, amqp, кешами и другие. 

Мы занимаемся разработкой и усовершенствованием общих компонентов системы, которые служат основой для построения приложения: много работаем с базовыми частями системы, упрощая тем самым процесс разработки для всех команд в компании. А еще мы помогаем решать технические проблемы, которые могут возникнуть во время разработки, и помогаем разобраться с инцидентами: например, с повышенным рейтом ошибок по какому-либо эндпоинту или резким увеличением потребления памяти с повышенной нагрузкой на систему. 

Логирование, метрики, алерты

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

Логирование. Мы хотим, чтобы общие части системы были прозрачными и предоставляли полезную информацию, которую мы сможем использовать при разборе инцидента. 

Логирование лучше держать в двух хранилищах:

  • Временное хранилище со всеми сообщениями с хранением в пару недель — этого достаточно для разбора инцидентов или для того, чтобы видеть работу системы здесь и сейчас.

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

Метрики. Логирование – это хорошо, но мало. Для прозрачной работы системы и разбора инцидентов нужны метрики. Также по метрикам можно легко посмотреть тренды по нагрузке, количеству пользователей системы, запросам и так далее. 

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

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

Конечно, мы также учим команды создавать свои метрики, рассказываем, куда их нужно отправлять и как визуализировать на графиках. Визуализация — лучший инструмент поиска причины инцидента. На основе метрик можно создавать алерты и другие нотификации. 

Пример визуализации 4хх ответов сервиса с разбивкой по хендлерам: 

Причинами таких всплесков могут быть как 429 (результат работы Rate limiter-a), так и 400 при ошибках в параметрах запроса от пользователя
Причинами таких всплесков могут быть как 429 (результат работы Rate limiter-a), так и 400 при ошибках в параметрах запроса от пользователя

Алерты. У SRE команды есть свои базовые алерты на доступность сервисов, нагрузку серверов и так далее, но они явно не покрывают все потребности бэкенд-команды. Поэтому мы создаем свои алерты для тех случаев, когда нам важно знать, что внутри приложения что-то пошло не так. 

Пример такого алерта — значительно увеличилось время ответа важного хендлера. Это еще не приводит к отказе работы сервиса, но подсвечивает проблему с быстродействием. Мы делаем алерты не только на случай, когда все плохо, но и для того, чтобы заранее предотвратить такие ситуации. 

Пример сообщения в Slack
Пример сообщения в Slack

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

Как сделать так, чтобы инцидент не повторился

Логирование, метрики и алерты помогают нам быстро реагировать, разбираться в причинах инцидентов и решать проблемы. Дальше нам нужно сделать так, чтобы инцидент не повторился. Для этого мы используем следующие инструменты: rate limiter, circuit breaker, caches.  

Кэши. Мы активно применяем кэши при взаимодействии с базами данных, чтобы разгрузить их и быстрее получить данные. Кэши создаем как локальные (с помощью Caffeine) внутри каждого инстанса сервиса, так и распределенные (на основе Redis). При таком подходе могут возникнуть проблемы, связанные с актуализацией значений в локальных кэшах распределенной системы, но мы умеем их решать, с помощью pub/sub механизма для рассылки событий инвалидации между сервисами. 

Rate limiter — контроль количества запросов, которые может сделать пользователь. Этот инструмент мы используем для уменьшения нагрузки на систему. Он помогает лучше распределять серверные мощности между пользователями и не забивать все пулы тяжелыми запросами или сломанными интеграциями. 

Мы умеем гибко конфигурировать rate limiter —  это позволяет давать больше возможностей тем, кому это действительно необходимо. Мы используем два типа контроля: контроль количества запросов за промежуток времени и контроль количества процессорного времени, которое затрачено на запросы. Это помогает избежать и большого количества мелких запросов, и тех случаев, когда пользователь укладывается в лимит, но его запросы очень медленные или ресурсоемкие. 

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

Circuit breaker (CB) — паттерн, который в случае возникновения проблем с доступностью сервиса перестает пропускать к нему запросы до тех пор, пока доступность не восстановится. Этот паттерн помогает нам быстрее восстановиться в том случае, если возникли проблемы с какой-либо частью нашей системы или внешней. 

Инструмент особенно полезен при решении проблем с сетевой связностью между компонентами. Запросы к системе, по которой открыт CB, перестают отваливаться по таймауту, а сразу завершаются с ошибкой. Это не забивает пулы и помогает быстрее получить ошибку. Мы считаем, что деградация лучше, чем полная неработоспособность. В некоторых случаях при срабатывании CB мы полностью обрываем все открытые соединения с проблемной системой и пытаемся заново установить связь. 

Заключение

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

Но самое главное, что хочется подчеркнуть — за всеми этими инструментами и технологиями стоят люди. Именно благодаря команде backend reliability специалистов, которые умеют эффективно использовать эти инструменты и всегда готовы найти решение любой проблемы, мы можем обеспечить высокое качество продукта. Мы постоянно ищем новые подходы и технологии, которые позволяют нам сделать наш сервис более надежным и учат нас справляться с любой нагрузкой. Мы стараемся заранее понять, какие части системы нужно улучшить, чтобы удовлетворить потребности растущего бизнеса. 

Буду рад ответить на вопросы и комментарии про работу нашей команды.

Комментарии (2)


  1. 0Bannon
    16.10.2023 21:39

    Чотко, умеете, могёте.


  1. SimSonic
    16.10.2023 21:39

    Жаль, что в статье нет никаких технических деталей. Только два названия, Redis и Caffeine.

    Хотелось глубины.