Почему самые высоконагруженные веб приложения мира это не всегда микросервисы?
Многие компании, которые разрабатывают самые высоконагруженные приложения, с миллиардами запросов в секунду, используют монолиты и монорепы. Ярким примером является Facebook и Instagram. В бэкенде это монолиты. Конечно, у них есть большое число других компонент, которые вынесены в отдельные сервисы, но основной backend, который принимает и обрабатывает запросы от фронтенда (веба или мобильного приложения), содержит бизнес логику - это монолит.
Backend Facebook изначально был написан на PHP в 2004 году. Далее его плавно мигрировали на собственный язык hacklang и собственную виртуальную машину hhvm. При этом он остался, по большей части, колоссального размера монолитом.
Аналогично, Instagram написан на python (django). Основная часть все еще остается монолитом.
Оба сервиса имеют миллиарды пользователей и обрабатывают невероятное число запросов в секунду. При этом они обладают колоссальной отказоустойчивостью и скорость разработки сервисов огромная. Время от того, как вы запушили комит до деплоя в prod проходит несколько часов.
Более того, весь код этих приложений находится в монорепе и используется trunk-based development. Т.е. все изменения сразу делаются в основной ветке разработки.
Почему так? Какие это дает преимущества?
Монорепа:
1) Проблема версионирования API решается на уровне компилятора. Если вы меняете какое-то API, то вы не сможете запушить это изменение в trunk до тех пор, пока не измените все call site (все места, где это API вызывается). Вам не позволит компилятор, ваш код просто не скомпилируется. Если у вас множество репозиториев, то изменение API в одном месте не блокирует вас запушить это изменение. Вы создадите новую версию вашего API. Всем клиентам нужно про это узнать, и делать процесс миграции на новую версию. Нужно менять код, зависимости и т.д. Очень часто это приводит к багам в проде. Когда клиент ожидает одного поведения или семантики API, а в проде уже задеплоена другая версия.
2) Полностью решается проблема dependency hell. Проблемы зависимостей на разные версии одной и той же библиотеки со стороны разных зависимостей вашего модуля. Круговые зависимости и т.д. Тут все решается автоматически на уровне компилятора.
3) Легкий поиск по коду. У вас весь код под рукой. Если он проиндексирован можно легко найти любой интересующий вас код.
В Амазоне отдельные репы. Там целая наука работы с зависимостями. Есть свои тулы, концепции и т.д. Там есть тул brazil, понятие version set и много всего другого. Это постоянно приводит к затыкам с зависимостями, багам в проде из-за версионирования. Часто пуш сторонней библиотеки может заблокировать ваш CI/CD пайплайн, т.к. у вас поломались зависимости.
Монолиты:
1) Высокая производительность. В микросервисах вызов функции происходит по сети, что работает за миллисекунды. В монолитах вызов происходит в рамках одного процесса и работает за наносекунды.
2) Нет проблемы версионирования API в проде. Это решается на уровне компилятора. Это типичная проблема микросервисов.
3) Легко тестировать. Вы можете протестировать все e2e. В микросервисах часто очень сложно или не возможно протестировать приложение e2e. Вы можете протестировать свою компоненту, но не весь функционал в целом. Особенно, если у вас под 100 тысяч микросервисов, как в условном Amazon.
Trunk-based development:
1) Отсутствие Merge-Hell. Если вы разрабатываете крупную фичу в отдельной ветке, ее потом сложно мержить в trunk. Мелкие и частые изменения предотвращают тяжелые конфликты вмерживания.
2) Можно сделать реальный и быстрый CI/CD. В Мета любое изменение вмерживается, компилируется, тестируется и деплоится в прод за несколько часов. Не нужно делать долгие, сложные и редкие релизы.
Post #1272
1.76K
- 👍 16
- ❤ 11