Почему масштабировать сложно в принципе?

Вавилонская башня вышла не особо масштабируемой
Вавилонская башня вышла не особо масштабируемой

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

Основная причина тут в том, что как только вы начинаете изменять какую-то большую систему, она начинает разваливаться. Ну, за исключением тех случаев, когда у вас вообще всё на 100% покрыто высокоуровневыми блэк-бокс тестами. Однако, в реальном мире история с покрытием тестами такова, что код современных приложений покрыт (в лучшем случае) примерно на 1%.

Может быть, 100% покрытие тестами — это реальность не только для библиотек, утилит или компиляторов (ведь мы можем формализовать их поведение математически), но и для веб-приложения? Да не, фигня какая-то...

В общем, к тестам мы ещё вернемся, а пока давайте перейдем чуток на другой уровень абстракции. Главная проблема в том, что обратная связь насчет правильности, корректности кода должна быть молниеносной. В идеале вообще мгновенной. Покрытие тестами — это тоже один из видов обратной связи. Storybook — визуальное представление обратной связи, зачастую достаточное для того, чтобы вы могли быстро верхнеуровнево оценить корректность кода.

Есть еще один вид обратной связи — фидбек от ваших QA. Как вы понимаете, мгновенной ее назвать сложно, потому что как только вы вводите в процесс связь «человек <-> человек», вы порождаете бюрократию.

Ситуации со сложным масштабированием: примеры

#1 Интеграция неочевидной сторонней системы платежей

Допустим, вы работаете над приложением, в котором есть функции онлайн-платежей. Вам надо интегрироваться со сторонней платежной системой. У этой системы есть некое API, которое может работать только при развертывании вашего кода в облаке. А в облаке — ограниченное число серверов, так что вам надо еще и подождать в очереди.

Чтобы ждать в очереди, надо отправить запрос своему менеджеру. Вдобавок у вас есть фронтенд- и бэкенд-разработчики, которым надо нормально скооперироваться, чтобы без проблем развернуть всё на этом сервере.

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

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

#2 Большая вымышленная вселенная

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

Подобное, кстати, можно часто видеть в голливудских (да и не только) фильмах. Причина тут простая: чем сложнее становится история, тем сложнее отследить ее согласованность. А проверка корректности вообще не гарантирует правильности, а лишь увеличивает бюрократический эффект. 

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

Польза мгновенной обратной связи

Плюсов тут множество, главный из которых (как мне кажется) — возможность отделить функциональные подсистемы и устранить ненужные DevOps- и бизнес-процессы, а также узкие места. Давайте немного подробнее про каждый пункт.

Отделение функциональных подсистем

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

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

Устранение ненужных процессов DevOps- и бизнес-процессов, а также узких мест

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

Что в итоге

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

Всё это подводит нас к другому вопросу — как достичь 100% покрытия высокоуровневыми блэк-бокс тестами в приложениях в реальном мире?

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


  1. cupraer
    07.07.2023 03:55
    +6

    Вы переоцениваете тесты.

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

    Тесты в принципе помогут не сильно, а если это не property-based тесты на умных моках, а просто какая-нибудь фигня типа юнитов и аксептанса — то и вовсе скорее навредят при масштабировании.


  1. Kelbon
    07.07.2023 03:55
    +1

    О чём статья? Какое то повторение + бесполезные примеры.
    Это вообще перл:

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

    Резюмирую: автор говорит "пишите сразу ужасную лапшу, даже не пытайтесь сделать хорошо, потом сделайте интегральные тесты сразу на всё, а потом через пару лет пытайтесь это всё распутать"

    Подход, очевидно, неприемлемый