- PVSM.RU - https://www.pvsm.ru -

При проектировании системы знание анти-паттернов и подвохов зачастую оказывается более полезным, чем знание самих паттернов. Отталкиваясь от этой идеи, я решил написать данную статью, чтобы рассказать о факторах, которые, на мой взгляд, приведут к созданию ненадёжных систем. В её основе лежит мой собственный опыт проектирования преимущественно распределённых корпоративных приложений. Будет здорово, если ниже вы поделитесь собственным опытом и полезными идеями по теме.
Человеческий можно назвать устройством по выявлению паттернов. Однако это довольно затратный процесс, и основная цель
Первый такой механизм, который является актуальным для данной темы – это ментальная модель [2]. Реальность излишне сложна [3], хаотична и запутана для восприятия нашим
Все модели ошибочны, но некоторые из них полезны.
— Джордж Бокс [5]
В целом все модели можно поделить на две группы:
Очень важен здесь именно контекст. Возьмём, к примеру, теорию тяготения Ньютона (кстати, теории – это тоже модели) и общую теорию относительности, обе из которых оказываются полезны в разных контекстах (плоское пространство-время при малых скоростях и, вероятно, искривлённое при околосветовых). Причём одна не заменяет другую. Так что, на мой взгляд, в проектировании надёжных систем очень важно неискажённое видение контекста.
Понятие надёжности программного обеспечения не имеет единого общепринятого определения. Некоторые специалисты говорят, что она подразумевает операционную надёжность, другие считают, что это понятие связано с пользовательским опытом, третьи подчёркивают корректность программ, а некоторые вообще путают её с отказоустойчивостью и доступностью (хотя всё это в определённых случаях может быть частью общей картины).
Поэтому в контексте текущей статьи мне необходимо определить, что именно я подразумеваю под понятием надёжности. Я использую этот термин согласно толкованию в английском языке. Надёжная система – это такая, которой можно верить, что она выполнит возлагаемые на неё задачи максимально качественно и при этом не станет делать того, чего от неё не просят. По началу это можно принять за корректность, но я думаю, что здесь речь о её надмножестве. К примеру, вы не станете доверяться медленной системе, которая ежеминутно падает, но при наличии достаточного количества времени всё же выполняет поставленную задачу.

Процесс решения задач
Игнорируя реальность, далеко не уйдёшь. Смысл здесь вполне очевиден, но очень часто что-то всё же упускается.
Позвольте объяснить:
Обычно мы стремимся всё для себя упростить, снизив материальные, умственные или иные затраты.
При этом для реализации решения в реальности у нас есть множество вариантов. Один из наиболее распространённых подходов (который нас и интересует) – это использование компьютерных систем с помощью программирования.
Единственная причина, по которой мы с помощью
Использование модели, которая не согласуется с реальностью достаточно точно, тоже создаст проблемы, поскольку в подобной модели реальность будет разворачиваться неожиданным образом. Например, предложенная Птолемеем геоцентрическая модель мира [7], оказалась даже более точной, чем гелиоцентрическая модель с круговыми орбитами небесных тел, но имела проблемы с описанием прочих элементов реальности, о которых в ту эпоху не знали. В свою очередь, гелиоцентрическая модель [8] с эллиптическими орбитами решала эти проблемы, так как была и более простой, и точнее описывала реальность. Заметьте, это не говорит о том, что есть лишь одна верная модель, а все остальные ошибочны. Как я уже писал выше, модели – это лишь инструменты для нашего понимания и решения задач. Не стоит путать их с реальностью.
Сам Птолемей в своём труде Альмагест пишет, что любая модель для описания движения планет – это просто математический инструмент. Поскольку не существует способа выявить среди моделей истинную, использовать нужно самую простую, которая даёт верные числа.
Вернёмся в индустрию ПО. Если вы проектируете корпоративную программу, то моделируете уже существующую модель системы, построенной на взаимодействии людей, структурах организации и бизнес-процессах (которые сложны сами по себе). Создание поверх одной модели другой, которая будет иметь какие-либо логические и концептуальные нестыковки, очень быстро приведёт одновременно и к повышению сложности, и к понижению комфорта рабочего процесса.
Нельзя решить бизнес-задачи с помощью дополнительного уровня технических усилий.
Здесь на помощь приходит предметно-ориентированное проектирование [9] (DDD). Под этим видом проектирования я подразумеваю стратегические паттерны и идеи, а не тактические вроде сущности и репозитория. Это учит нас находить существующие бизнес-модели вместо того, чтобы пытаться создать очередную с возможными нестыковками. Таким образом мы уменьшаем общую сложность и берём в расчёт всесторонние социотехнические факторы.
Особенно это актуально в случаях, когда существующие модели бизнеса являются уже не новыми, а довольно устоявшимися и зрелыми.
Делай всё настолько простым, насколько возможно, но не проще.
— Альберт Эйнштейн
Система, которая стремится излишне упростить реальность, в лучшем случае, утрачивает часть важных концепций бизнеса, а в худшем полностью уходит не в том направлении.
Моим любимым примером подобного феномена является ситуация, когда разработчики стремятся внести в систему больше согласованности, чем нужно. В итоге конечный результат оказывается лишён важного принципа, необходимого для разрешения возможных конфликтов бизнес-процесса, а мы получаем медленные и неудобные в обращении куски ПО.
Например, в ходе банковской транзакции активы передаются не сразу (атомарным образом), а в течение некоторого времени находятся в подвешенном состоянии, то есть уже списаны с исходного счета, но на счёт получателя ещё не зачислены. Попытка смоделировать этот процесс атомарным образом потребует использовать протокол двухфазного коммита (2PC), что почти всегда будет признаком плохого моделирования [10].
В качестве более распространённого примера можно привести корзины для покупок, которые стремятся обрабатывать складские операции атомарным образом. Такой подход будет страдать от аналогичной проблемы, не учитывая возможность истощения складских запасов или корректировки количества определённых товаров ввиду инцидента, сделавшего их негодными.
Такие проблемы моделирования практически всегда приводят к состоянию гонки.
В реальном мире не существует состояния гонки, если только ты не упускаешь принцип.
Дилберт: О, нет! Излишний уровень абстракции сделал нас невесомыми! [11]
(фраза из м/с «Дилберт», ссылка может не работать, — прим. пер.)
Ещё один случай неудачного моделирования связан с излишним абстрагированием, в результате которого также утрачиваются важные принципы. К примеру, несмотря на то, что с математической точки зрения вызов метода можно заменить удалённым вызовом, такой приём будет подразумевать, что сеть безопасна, хотя по факту это не так. При этом также усложнится обработка ошибок, а в худшем случае возникнут сбои, которые невозможно обработать корректно ввиду игнорирования природы распределённых систем.
Поясню последний аргумент. Мы не можем знать, был ли некий метод выполнен удалённо, прибыл ли ответ в нужное время, и достиг ли он вообще точки назначения. Это фундаментальная проблема, и она явно демонстрирует, что её при таком подходе не решить.
Ещё один распространённый пример касается моделирования асинхронного по своей природе взаимодействия в виде синхронного. Это только всё усложняет, поскольку так вы сужаете возможные сценарии до недостаточно обширной области задачи. В результате вы будете либо игнорировать проблемы, либо с трудом стараться понять эвристику, чтобы частично исправить сложности, не связанные с вашей основной задачей.
Именно поэтому использование RPC при проектировании надёжных распределённых систем практически всегда будет плохой идеей.
При внедрении конкурентности или любого иного вида распределения работы вы изменяете законы физики собственной программы. Вы изменяете природу времени с ньютоновской модели, в которой существуют уникальные глобальные часы, до физики множественных тел из теории относительности, где у каждого объекта есть собственные относительные часы. При этом вы также переходите от плоской логики к темпоральной [12], при которой невозможно делать заключения без учёта поведения времени.
Ваши задачи усложняются на несколько порядков, и их решение затягивается гораздо дольше. Добавьте сюда распределённые системы, и вы получите ещё большую сложность.
Непонимание отличия распределённых/конкурентных систем от наиболее привычных для разработчиков является причиной многих бизнес-провалов и мучений для связанных с этим людей.
Мой первый закон проектирования распределённых объектов: не распределять объекты.
— Мартин Фаулер [13]
Это настолько обширная тема, что даже целая книга раскроет её лишь поверхностно. Но я всё же приведу несколько типичных заблуждений:
Заметьте, что под асинхронностью я имею в виду не использование брокеров сообщений, а асинхронную коммуникацию. Её можно реализовать с помощью HTTP, к примеру, используя технологию pull вместо push-and-wait, как при использовании Atom feeds вместо RPC;.
В распределённых системах есть всего две существенных проблемы:
2. Доставка строго один раз
1. Гарантированный порядок сообщений
2. Доставка строго один раз— Матиас Верраес [15]
Моделирование реальных приложений – это сложная задача, и каждой системе значительного размера требуется значительный объём командной работы, которая далеко выходит за возможности отдельного человека. Трудится в команде нелегко. Этот навык необходимо нарабатывать, как и любой другой, но для многих данный процесс не является естественным, поэтому обычно здесь требуется наставничество и хорошее руководство. Это сложная задача, поскольку в ней необходимы не только навыки руководителя, но и подходящие условия для их использования. А для большинства отдельных людей и даже команд эти условия обычно находятся вне зоны контроля [15].
Однако, когда это всё же удаётся, то надёжные системы создаются в надёжных организациях, где выработана культура непрерывного совершенствования и открытой коммуникации. В таких компаниях команды строятся вокруг возможностей и обладают достаточной автономией для выполнения необходимых задач, а также при необходимости могут влиять на организацию в целом, улучшая её.
Ригидные организации неспособны создавать надёжные системы, поскольку это требует постоянного улучшения, которое в них реализовать не получится. К примеру, структура компаний, построенных вокруг авторитета, противоположна той, что способна привести к успешным результатам, поскольку в них отсутствует автономия. Люди, обладающие наиболее актуальной информацией и навыками, не принимают в таких компаниях решений.
Как гласит закон Конвея [16]:
Любая организация спроектирует такую систему (в широком смысле), структура которой будет копировать структуру коммуникации этой организации.
— Мелвин Е. Конвей
Из этого следует, что структура организации играет важнейшую роль, определяя конечную структуру создаваемой ей системы. Если также учесть, что организации представляют собой системы, состоящие из людей, то можно сделать вывод, что игнорирование потребностей и опыта этих людей, а также плохое управление, однозначно будут вести к созданию ненадёжных систем. Мусор на входе – мусор на выходе.
И хотя это может прозвучать тривиально или излишне очевидно, не каждая команда или отдельный специалист обладают актуальными навыками, необходимыми для разработки или проектирования всевозможных систем. Разные люди обладают не только разным опытом и умениями, но и мотивацией. В то же время большинство проектов по созданию ПО зачастую выглядят как простые CRUD-приложения (по крайней мере — внешне), с которыми знакомо большинство разработчиков. Однако б’ольшая часть критически важных систем, для которых надёжность является наиболее важным критерием, к таковым не относятся.
Принуждение команд или отдельных специалистов, которые не заинтересованы в проекте или лишены необходимых навыков, является прямым путём к созданию ненадёжных систем, частым сбоям и, скорее всего, текучке кадров.
Вы можете выбирать, из каких людей собирать команду, но у вас не выйдет сформировать устойчивый и эффективный коллектив искусственно. Тут нет коротких путей и схитрить не получится. Потребуется довольно долго вкладывать серьёзные усилия и средства в команды и отдельных специалистов. И если вам достаточно повезёт, то в итоге вы получите нужных людей и устоявшиеся сплочённые команды.
Последним в этом пункте я упомяну особенности управления в условиях интеллектуального труда. Люди не являются просто кадрами, и их нельзя раскладывать на составляющие уравнения (к примеру, в виде человеко-часов). Если мыслить иначе, то это оказывается той самой проблемой несостыковки ментальной модели с реальностью, о которой говорилось выше, но теперь уже в сфере социальных систем.
Очень уж часто вместо моделирования фактических задач руководство фокусируется на инструментах. Из уст неопытных архитекторов ПО, или когда архитекторов вообще нет, это зачастую может звучать как-то так:
Мы можем решить эту задачу, если внедрим Kafka там, MongoDB вон там, а Django здесь, и развернём всё это на высокодоступном кластере k8s, который на случай апокалипсиса будет размещён на трёх континентах.
— Подход проектирования ради резюме, ведущий к созданию сайта электронной коммерции с десятью посетителями в месяц.
Всё это происходит в первую очередь из-за синдрома блестящего объекта [17] или концепции разработки ради резюме [18], у которой даже есть свой манифест [19]!
Разработка ради резюме
Мы ценим:
- конкретные технологии превыше рабочих решений;
- найм на основе присутствия в резюме заумных слов, а не подтверждённых трудовых достижений;
- креативные названия должностей превыше технического опыта;
- реагирование на тренды, а не более прагматичные решения.
Такой подход даже близко не приведёт к хорошим результатам.

Часть моста Майлс-Глейшер с клуджем (временным решением) после землетрясения
Вполне нормально временами применять обходные пути, когда ситуация срочная, или это действительно необходимо. Но в долгосрочной перспективе утрата общей картины порушит всю модель. Любые самые грамотные и полезные проекты, какие только придумывал человек, окажутся бесполезны, если этот факт игнорировать.
Программное обеспечение должно быть мягким (игра слов: software должно быть soft, — прим. пер.), податливым и удобным для изменения. При этом оно также является сложным, поскольку в основном стремится решить сложные задачи – простые уже были решены в прошлом. Всё верно, по мере развития технологий мы решаем всё более сложные задачи. Одним из подводных камней проектирования сложных систем является проблематичность выявления взаимосвязей между элементами, которая мешает всё грамотно спланировать. Некоторые при этом идут путём решения сложных задач с помощью создания сложных систем.
Такой подход не сработает, подобно тому как нельзя построить сложную систему в один заход. Это бы означало, что человек смог осмыслить её всецело сразу, а значит — система не была сложна. Сложные системы всегда являются результатом поэтапного внесения изменений в более простые.
Работоспособная сложная система неизбежно является следствием развития простой работоспособной системы. Сложная система, спроектированная с нуля, никогда не заработает, и её не получится подлатать, чтобы этого добиться. Начинать необходимо с простой системы.
– закон Галла
Как бы то ни было, игнорирование эволюции, итеративного проектирования и непрерывного совершенствования зачастую не ведёт к созданию ненадёжных систем, поскольку для реализации такого проекта требуется невероятное количество времени, и к моменту, когда он окажется готов (если окажется), пользы от такого проекта уже не будет, и никакой системы он не построит — хоть надёжной, хоть безнадёжной.
Telegram-канал с полезностями [20] и уютный чат [21]
Автор: Дмитрий Брайт
Источник [22]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/arhitektura-po/380514
Ссылки в тексте:
[1] мозг: http://www.braintools.ru
[2] ментальная модель: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8
[3] сложна: https://economictimes.indiatimes.com/news/science/cern-has-an-exciting-discovery-3-new-exotic-particles/pentaquark-tetraquarks/slideshow/92703027.cms
[4] объективную реальность: https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C
[5] Джордж Бокс: https://en.wikipedia.org/wiki/All_models_are_wrong
[6] некоторыми из своих идей: https://www.huffpost.com/entry/6-things-aristotle-got-wr_b_5920840
[7] геоцентрическая модель мира: https://ru.wikipedia.org/wiki/%D0%93%D0%B5%D0%BE%D1%86%D0%B5%D0%BD%D1%82%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D0%BC%D0%B8%D1%80%D0%B0
[8] гелиоцентрическая модель: https://ru.wikipedia.org/wiki/%D0%93%D0%B5%D0%BB%D0%B8%D0%BE%D1%86%D0%B5%D0%BD%D1%82%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D0%BC%D0%B8%D1%80%D0%B0
[9] предметно-ориентированное проектирование: https://en.wikipedia.org/wiki/Domain-driven_design
[10] плохого моделирования: https://www.enterpriseintegrationpatterns.com/docs/IEEE_Software_Design_2PC.pdf
[11] Дилберт: О, нет! Излишний уровень абстракции сделал нас невесомыми!: https://dilbert.com/strip/2012-01-07
[12] темпоральной: https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BC%D0%BF%D0%BE%D1%80%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0
[13] Мартин Фаулер: https://martinfowler.com/bliki/FirstLaw.html
[14] крохотных частиц: https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%B4%D0%B0%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B2%D0%B7%D0%B0%D0%B8%D0%BC%D0%BE%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F
[15] Матиас Верраес: https://twitter.com/mathiasverraes/status/632260618599403520
[16] закон Конвея: https://en.wikipedia.org/wiki/Conway%27s_law
[17] синдрома блестящего объекта: https://www.parkersoftware.com/blog/shiny-object-syndrome-in-software-development/
[18] разработки ради резюме: https://www.wearedevelopers.com/magazine/resume-driven-development
[19] манифест: https://rdd.io/
[20] Telegram-канал с полезностями: https://inlnk.ru/dn6PzK
[21] уютный чат: https://inlnk.ru/ZZMz0Y
[22] Источник: https://habr.com/ru/post/698014/?utm_source=habrahabr&utm_medium=rss&utm_campaign=698014
Нажмите здесь для печати.