Введение

Этот пост написан в основном для тех беспечных разработчиков, которые пишут код без учёта эксплуатации.

Что такое эксплуатация? Вики определяет эксплуатацию как “использование чего-либо”. Как используются программы? Их устанавливают, конфигурируют, после чего убеждаются в корректности работы в соответствии с инструкцией.

Чтобы сделать программу эксплуатируемой необходимо предоставить документацию для всех этих процессов.

По правде говоря, проекты (а иногда даже продукты) редко сопровождаются хотя бы какой-то документацией, не говоря уже про документацию по эксплуатации. Подход “Это как-то работает”, “просто перезапусти”, вот это всё.

Поэтому я попытаюсь объяснить, как сделать веб-сервисы эксплуатируемыми. Есть один достаточно известный ресурс по этой теме, который более обширный и формальный, чем моя статья.

Стандартизируй!

Под этим я имею ввиду две вещи.

Сделай стандарт документации по эксплуатации

Во-первых, спроси своих коллег из отдела эксплуатации (админов). Особенно если уже есть какие-то сервисы в эксплуатации. Что они используют? Какой информации им не хватает?

Во-вторых, изучи свои проекты (и уже в эксплуатации и в ранней разработке). Подумай обо всех местах, которые могут быть сконфигурированы, о ситуациях, которые могут случиться. Думаешь, твою систему так легко понять? Я разочарую: совсем нет.

После сбора общей информации нужно написать шаблон документации по эксплуатации и всем его показать, обсудить, затем улучшить.

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

Сделай процесс документирования обязательным для всех разработчиков

С этим немного сложнее. Если ты — тимлид или старший разработчик, то используй свою власть чтобы сделать документирование эксплуатации обязательным. Если ты рядовой сотрудник — используй техники убеждения социальную инженерию, меритократические наклонности, своего начальника, свою репутацию, веди себя как полная скотина, но заставь всех писать документацию по эксплуатации. Просто поверь мне, это спасёт тебя лично от бессонных ночей (особенно если ты — тимлид или менеджер).

Сделай свою систему эксплуатируемой

Это тоже непросто. Всё вот это добро из 12-factor — это сюда.

ENV-конфиги проекта

Это то, что я видел очень много раз. И каждый раз я старался от этого избавиться. Если в папке config есть что-то кроме production- и test-конфигов — всё плохо.

Просто представь: в час ночи сервер БД падает без шансов на восстановление, но у админов есть реплика, на которую можно переключиться очень быстро (в пределах SLA) просто поменяв IP-адрес (или доменное имя) БД в приложении. Но с хардкодом в production-конфиге это делается только через изменение кода и редеплой приложения. И вот она, бессонная ночь. И не одна.

Поэтому, чтобы сделать систему конфигурироемой “находу”, нужен либо config-provider, либо просто получение значений из ENV-переменных (со значениями по-умолчанию). Это уже добавит достаточно много сна в беспокойную жизнь разработчика.

И конечно, конфигурацию (ENV-переменные или config-provider’ы) очень даже стоит документировать. Поверь мне.

Добавь проверки запущенности (readiness) и работоспособности (liveness)

Или, как некоторые их называют, хелсчеки. Я не про кубернетисы.

Зачем? Админам желательно знать, когда приложение уже запустилось (readiness) и когда оно упало (liveness). Обычно веб-приложениям хватает ответа 200 OK на запрос / для обеих проверок.

И затем опиши это всё в документации.

Сделай кастомный endpoint для мониторинга

Фишка в том, что скорее всего у админов уже есть какой-то инструмент мониторинга. Нет ничего плохого в том, чтобы помочь им.

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

Мы (на тех проектах, которые я разрабатывал) использовали /healthcheck с примерно следующим содержимым:

db ok
smtp ok
rabbitmq ok

И опиши это в документации по эксплуатации.

Опиши все сервисы

Используешь СУБД? Веб-сервер? Отправляешь email’ы? Опиши!

Для каждого описываемого сервиса нужно описать:

  1. Откуда брать. Сборка кода? Docker? RPM-пакеты?
  2. Как запустить: команды, аргументы, флаги, вот это всё.
  3. Что сделать при первом старте. Например, импортировать какие-то данные “по-умолчанию” (возможно специальной командой).
  4. Зависимости. Не думаю, что есть смысл запускать сервер приложения до запуска СУБД.
  5. Масштабируемость. Веб-сервер достаточно легко (авто)масштабируется. А вот с масштабированием СУБД обычно всё не так хорошо.
  6. Требуемые ресурсы для работы. Память, процессор, диски, сокеты, inode’ы.
  7. Бэкапы. Что, как и когда нужно бэкапить и как это нужно восстанавливать.
  8. Зачем нужен этот сервис. Что именно он делает. Это поможет понять, можно ли перезапустить этот отдельный сервис или всё куда сложнее.

При этом нужно помнить, что то, что ты обычно называешь “приложением” на самом деле тоже является сервисом. Puma с рельсами на борту — HTTP-сервер. Cowboy с фениксом на борту — тоже HTTP-сервер. Java со спрингом — это очень плохая идея нужно от такого избавляться год назад.

Опиши сеть

Какие сервисы должны смотреть в мир? Какие сервисы должны смотреть друг в друга? Всё это — очень важная информация о том говнокоде, над которым ты сидел месяцами (или даже годами).

Ручки

Есть скрипт полной очистки? Кнопка пересборки кеша?
Нет — сделай.
И опиши.

Вместо заключения

Этим, на самом деле, список не ограничивается. Не надо “просто писать код”. Нужно делать эксплуатируемые сервисы.