К основному содержимому
к презентации
Конспект выступления2019

WEB глазами бекендера: что нас ждет впереди

Двадцатиминутный доклад на GetIT Meetup: Александр Поломодов, отвечающий за разработку в привлечении Tinkoff, проходит пять слоёв бэкенда — организацию кода, хранение данных, проектирование систем, инфраструктуру и автоматизацию, — показывает, куда каждый из них движется, и в вопросах из зала объясняет, почему одно их приложение живёт на голом железе.

GetIT Meetup7 минут

Конспект сокращён относительно полного выступления; примеры и оценки передают опыт и позицию автора.

Основная линия материала
01

Привлечение: от спагетти к onion

Александр начинает со знакомства: он окончил один из лучших технических вузов России, работал разработчиком и тимлидом в разных компаниях, а два с половиной года назад пришёл в управление привлечением. Его командам достались неавторизованная зона сайта — главная страница и всё, что видно до входа в личный кабинет продукта, — и своя система управления контентом, через которую заводят новости, вакансии и другие страницы для веба и отчасти для мобильных приложений. Вторая часть работы — автоматизация закупки рекламы: бюджет на привлечение новых пользователей большой, и Александр перечисляет пять самых популярных каналов, среди них контекстная реклама и реклама в социальных сетях. Пользователей много, поэтому гипотезы проверяют до выката: A/B-, сплит- и multivariate-тесты, а если результат вышел неоднозначным — персонализация страниц для отдельных сегментов. На весь рассказ у него двадцать минут, поэтому каждый раздел он закрывает слайдом с книгами.

Первый слой эволюции — код. Когда-то писали спагетти: структуры не видно, непонятно, как внести изменение, чтобы не выстрелило в другом месте, и Александр признаётся, что сам так начинал. Потом появилась слоистая архитектура — слой отображения, слой бизнес-логики, слой хранения, — и это был большой скачок вперёд, но правил, кто от кого зависит и как слои общаются между собой, она не задавала. Пробел закрыла концепция dependency injection, а с ней onion- и гексагональная архитектуры: внешние слои, то есть интерфейсы и сервисы, зависят от доменной области, а сама доменная область не меняется от того, каким интерфейсом система разговаривает с внешним миром. К разделу он прикладывает подборку книг и статей про то, как организовывать код правильно.

02

От нормальных форм к микросервисам

Хранение данных прошло похожий путь. Сначала состояние лежало в файловой системе, и разработчик описывал не только какие данные ему нужны, но и как найти их на диске, в какой директории и как дописать файл, — долго, больно и без переиспользования. Затем пришёл Кодд с реляционной теорией и стандартом SQL, который отлично зашёл учётным системам: сущности, связи, нормальные формы, а данные забираются декларативно — искать их будет планировщик базы. В 2010-х появились сценарии, где реляционная база недостаточно масштабируется горизонтально или слишком медленно отвечает, и родился NoSQL: термин, вспоминает Александр, начался с поиска незанятого хэштега для митапа, а сейчас его уже не стоит расшифровывать. Такие решения разменяли гарантии реляционных баз — SQL, ACID, иногда и транзакции — на BASE с базовой доступностью и согласованностью в конечном счёте. Держать консистентность на уровне приложения оказалось неудобно, и появился NewSQL: горизонтальное масштабирование, работа в разных регионах, транзакции и привычный синтаксис. Здесь он вспоминает CAP-теорему и приводит white paper про Google Spanner с межрегиональными транзакциями и SLA в пять девяток, а лучшей книгой раздела называет Designing Data-Intensive Applications.

Проектирование систем начиналось с монолита, в котором лежала вся логика: любое изменение требовало полного регресса, зависимости были непонятными, а монолит со спагетти-кодом Александр называет смаком для гурманов. Сервис-ориентированная архитектура обещала собирать приложение из готовых сервисов, но превратилась в набор тяжёлых интерфейсных систем, торчащих в интернет со своими описаниями: интегрироваться с ними было сложно, и идея не полетела, хотя очень старались. Микросервисы, замечает он, концептуально отличаются от SOA только приставкой «микро»: какого размера должен быть сервис, чтобы называться микросервисом, толком никто не знает, зато говорить, что ты пилишь микросервисную архитектуру, сейчас популярно. Дальше — serverless и functions as a service: события и хендлеры, для части задач отличный подход, но логику оркестрации вызовов приходится зашивать в клиента. Из книг здесь Сэм Ньюман и небольшая книга о типовых ошибках, когда предметную область режут слишком мелко; из манифестов — двенадцатифакторное приложение и шутка про однофакторное.

03

Железо, Kubernetes и вопросы из зала

Где всё это исполняется — отдельная лестница. Александр помнит железные машинки, которым администраторы давали женские итальянские имена: вспоминать, что где развёрнуто, было как перебирать подружек. Железо подводит с изоляцией приложений и утилизацией ресурсов, а выдавать каждому по машине слишком дорого, поэтому пришла виртуализация x86 — её предложили ребята, начинавшие с научного проекта, который превратился в хороший бизнес, — а следом виртуализировали диски и сеть. Простаивающие мощности логично продать: AWS пристроил избыточное железо вне пиковых сезонов и держит большую часть рынка, конкурируют с ним Microsoft Azure и GCP. Контейнеры срезают стоимость гостевой ОС и хорошо ложатся на микросервисы, но руками их не пожонглируешь — нужен оркестратор, и де-факто им стал Kubernetes, по которому Александр сертифицированный администратор. Вершина лестницы — платформа как сервис, куда закидываешь код и платишь за ресурсы. Автоматизация должна успевать за этими движущимися частями: от выкладки артефактов руками через Capistrano и Fabric лет пять назад до CI/CD вроде Bamboo и TeamCity, а дальше — хаос-инженерия Netflix, где проблемы вносят внутрь приложений и смотрят, как предотвращаются каскадные отказы.

Что впереди: монолит, который был два с половиной года назад, распался примерно на 45 микросервисов — выкатывать их удобно, а сквозное изменение вроде единого формата межсервисного взаимодействия вместо JSON требует обновить все сорок пять. Базы, если позволяет безопасность, лучше брать как сервис: своего хорошего DBA у большинства нет, а часть нагрузок вроде перегона картинок в удобный формат закрывает FaaS без своей очереди. Первый вопрос из зала — чем слоистая архитектура отличается от onion — Александр откладывает до перерыва как слишком долгий. Второй: всякому ли бизнес-домену подходят эти паттерны? Контрпример у него свой: приложение, покупающее рекламу на аукционах в реальном времени, укладывается в бюджет ответа 100 миллисекунд, поэтому его не режут на сервисы, а на общем железном хосте оно упиралось в потолок из-за шумных соседей: всё решают нефункциональные требования. Третий вопрос, про GCP и согласование с безопасностью, приводит к гибриду: в облаке веб и управление контентом, данные и связанные с ними сервисы остаются в московских дата-центрах, ходят между ними по выделенному каналу, а дата-центр Google в Финляндии даёт 17 миллисекунд.

Выводы

Что стоит унести с собой

  1. 01Слои дали структуру, но не правила зависимостей: их задали dependency injection и onion-архитектура, где домен не зависит от интерфейсов общения с внешним миром.
  2. 02NoSQL разменял гарантии реляционных баз на горизонтальное масштабирование, а NewSQL вернул транзакции и SQL: Google Spanner держит на этом пять девяток доступности.
  3. 03SOA и микросервисы расходятся только приставкой; сорок пять сервисов делают выкат дешёвым, а любое сквозное изменение — дорогим.
  4. 04Нефункциональные требования сильнее моды: приложению с бюджетом ответа в 100 миллисекунд подходит монолит на железе, а не общий хост с шумными соседями.

Источники