Открытый канал ID 76936775713522

Архитектоника в ИТ

Канал Александра Межова с заметками про ИТ-архитектуру и разработку.

TG https://t.me/arch_and_dev

Сайт - https://amezhov.ru/blog/

Каналов в рубрике
1 753
Место этого канала
№ 1 035
Открыть рубрику →
Открыть в MAX

Публикации за период

По реакциям

Поиск и вся лента — после бесплатной регистрации. Свои даты — по подписке; владелец канала видит их бесплатно. Сортировка по реакциям — по подписке. Зарегистрироваться

Загрузка…

Признак нарушения архитектурных границ: чужой ID

Представьте: меняем особенности реализации своего сервиса, а дорабатывать приходится и его клиентов. Почему внутренняя интеграция стала общей проблемой? Предлагаю ещё один признак для проверки границ и потренировать архитектурную насмотренность. 🔭

Контекст

Конкретный пример.

Врач завершает осмотр и назначает следующий визит. Бэк мобильного приложения (BFF) сохраняет протокол осмотра и вызывает сервис задач. Тот бронирует время в календаре врачей и создаёт задачу на следующий визит.

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

Бронированием занимается сервис задач, а подтверждением – BFF. Поэтому сервис задач вынужден вернуть клиенту ID, полученный от календаря.

Проблема

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

Чем это грозит?

⚠️ Излишняя связанность. BFF участвует в бизнес-процессе, часть которого скрыта внутри сервиса задач. Стоит проверить, обосновано ли такое разделение ответственности.

⚠️ Хрупкость контракта. При замене календаря могут измениться формат и смысл ID. Тогда изменения затронут всех его потребителей.

⚠️ Рассогласование данных. При наличии доступа внешние системы могут изменить бронь по её ID в обход сервиса задач и нарушить связь между задачей и записью календаря.

Выявление проблемы

Признак нарушения границ:

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

Признак удобен при проведении ревью и подталкивает к обсуждению вопросов ответственности и стоимости будущих изменений:

▫️ Откуда пришёл ID?
▫️ Зачем он потребителю?
▫️ Является ли ID частью общесистемного контракта?

Это согласуется с идеей защищать потребителей от изменений за стабильным контрактом.

Варианты решения

Вариантов много, вот основные:

▫️ Оркестратор. Отвечает за завершение всего сценария и обработку частичных сбоев. Опционально: передать подтверждение сервису задач, если весь сценарий входит в его ответственность, тогда BFF получает результат без ID календаря.

▫️ Собственный ID. Сервис задач хранит соответствие между своим ID и ID календаря. Это отделяет публичный контракт от идентификаторов зависимости. Однако придётся адаптировать подтверждение: оно пока ожидает ID календаря. Обход сервиса задач потребует специально "добывать" исходный ID и строить отдельную интеграцию. Это усложняет и удорожает обход, вызывает вопросы при реализации и помогает удерживать границу. Но не заменяет контроль доступа.

▫️ Контроль доступа. Ограничить изменение броней, созданных сервисом задач, разрешёнными участниками процесса. Отдельно обеспечить проверку бизнес-запрета отмены подтверждённой брони. Это ограничивает обходные изменения, но требует настройки прав и специфичных проверок; зависимость публичного контракта от календаря остаётся.

▫️ Общесистемный контракт. Осознанно оставить ID календаря в API, договорившись о его смысле, стабильности и правилах изменения броней. Меньше переделок сейчас, но сильнее связанность.

Как выбрать

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

Раскрытие детали реализации может стать практически необратимым решением: если другие команды построят на ней свои процессы, убрать её без их согласия и миграции уже не получится!

Короче, старайтесь не выносить сор из избы 😃

#tip #arch
Просмотры: 8
Перейти в пост Открыть в MAX Сообщить о неточности
Показатели эффективности работы

Все показатели зелёные, а проблемы остались. Как так?

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

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

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

1️⃣ Проектируем механизм

"Нужно точнее оценивать задачи" – понятное пожелание. Но в основе изменения должна быть гипотеза с чёткой формулировкой: если – то – потому что.

Согласитесь, что это слабая гипотеза: "Если установить лимит на Estimate Time, то планирование станет точней, потому что сотрудники начнут делать декомпозицию задач, лучше продумывая детали реализации". Лимит может подтолкнуть к размышлениям, но скорей научит дробить задачи для прохождения формальной проверки. Неопределённость при этом останется.

Другой вариант: "Если декомпозицию начинать делать с уровня бизнес-анализа, то планирование станет точней, потому что задачи на разработку станут дозированными и понятными". Здесь начинаем раньше разбирать бизнес-проблему на небольшие сценарии с понятным результатом и критериями приёмки. При сопоставимой загрузке команды ожидаем уменьшения разброса времени выполнения сценариев и колебаний их количества за спринт. А точность прогноза проверяем, сравнивая предполагаемую длительность с фактической.

Команде "разброс времени" поможет находить причины задержек и улучшать декомпозицию. Руководству "колебания количества принятых сценариев" покажут, какой объём работы команда способна предсказуемо поставлять.

Вторая гипотеза тоже может не подтвердиться! Но мы понимаем, что меняем, почему ожидаем эффект, когда и по каким показателям увидим результат или пересмотрим решение.

2️⃣ Контролируем корректность

Если разработка ускорилась, но подготовка задач стала занимать вдвое больше времени, смотрим на весь путь поставки: должен быть конвейер, а не водопад. Если количество сценариев за спринт возросло вместе с количеством багов; или потому, что спринты стали не по 2, а по 3 недели.

Любой целевой метрике нужны контр-метрики – противовесы, которые помогают увидеть перекос.

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

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

3️⃣ Подводим итоги

Для работы с метриками эффективности выделяем несколько правил:

▫️ Каждая метрика сопровождается гипотезой. Что и для чего меняем, какого эффекта ожидаем и почему.

▫️ Каждая метрика сопровождается контр-метриками. Чтобы видеть аномалии и цену результата.

▫️ Для каждой метрики определяем: текущий уровень (как точку отсчёта), целевое значение (как желаемый результат), период ожидания эффекта и период фиксации (сколько времени уровень должен удерживаться, чтобы мы считали его достигнутым, а не единичным всплеском).

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

〰️〰️〰️

Для закрепления темы предлагаю посмотреть мультфильм. 😃

// Выражаю благодарность Руслану Сафину как идейному вдохновителю для этого поста. 🔥

#view
Просмотры: 17
Перейти в пост Открыть в MAX Сообщить о неточности
А ты придумал задачу для Яндекса?

3 октября (суббота) пройдёт конференция Яндекса "Я про бэкенд" – в Москве и онлайн. Участие бесплатное, но нужна регистрация. В программе – архитектура и эксплуатация систем вокруг AI, потоковая обработка данных и отказоустойчивость.

➡️ Меня особенно заинтересовала секция с архитектурной задачей. Зрители присылают свои кейсы, организаторы выбирают один, а backend-разработчики Яндекса разбирают его в прямом эфире. Причём решающий увидит условие впервые. Пожалуй, хороший повод посмотреть, как специалист из топовой компании и с большим опытом выясняет требования и ищет компромиссы.

Решил тоже подать заявку – с задачей поиска/фильтрации медицинских документов, о которой уже писал ранее. Если кратко:

25 млн пациентов, (уже) 7 млрд документов и ещё ~5 млн новых каждый день. В среднем у пациента всего 200 документов, и поиск по его медицинской карте должен укладываться в 200 мс на P99. Но тот же сервис должен искать по всей базе за <5 секунд на P99, поддерживать произвольные сочетания фильтров и учитывать изменения документов не позднее чем через 1 секунду после сохранения. Запросы почти всегда идут без ограничения по периоду создания, а хранить данные нужно десятилетиями.

Это вполне прикладная задача: поиск нужен врачам каждый день. Задача сложная, и мне было бы очень интересно посмотреть, насколько мои идеи близки или далеки от того, что могут предложить инженеры Яндекса.

Но помимо прочего хотелось бы посмотреть на ход доказательства.

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

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

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

〰️〰️〰️

Пока Яндекс думает, решать или не решать, анонсирую три ближайших события:

📆 24 сентября, 19:00-20:00 МСК – Открытая сессия "Нейроколлеги в SourceCraft: когда код пишут не только люди". Тут ссылка на YouTube-трансляцию.

📆 25 сентября – LeTeam, фестиваль LentaTech в Санкт-Петербурге и онлайн. Участие бесплатное, по регистрации. Мероприятие больше для тех, кто в ретейле, но мне было бы интересно посмотреть на два доклада (в 15:00 МСК): "Трансформация платформы данных" и "Почему AI-фичи быстро прототипируются и долго доходят до продакшена".

📆 28 сентября – 2 октября – Podlodka Techlead Crew, онлайн-неделя "Techlead в эпоху AI". Про работу техлида, внедрение AI в разработку и оценку его пользы для команды. Это Подлодка, тут все доклады ожидаемы и хороши. :)

#conf
Просмотры: 18
Перейти в пост Открыть в MAX Сообщить о неточности
Где начинается декомпозиция

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

Представьте: наверху возникает бизнес-проблема, а до команды она доезжает в виде задачи "Создать сервис X". К ней прилагается подробный алгоритм: добавить таблицу, реализовать обработчик, подписаться на топик. Вроде бы написано много, но ответа на главный вопрос нет: какую проблему и для кого мы решаем?

Дальше неопределённость пытаются победить детализацией. Задачу раскладывают на подзадачи, каждую оценивают с разных сторон и в разных плоскостях – часах, story points, попугаях; составляют подробный план на недели вперёд и регулярно его переделывают. Кажется, что чем больше деталей, тем точнее прогноз. На деле получается точный план выполнения не очень понятой работы.

Детализация не создаёт понимания. Она лишь делает непонимание более подробным.

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

Бизнес-анализ раскладывает проблему на небольшие результаты, ценные для пользователя или заказчика. Затем системный анализ уточняет поведение, сценарии и ограничения. Архитектура определяет структуру решения. И только после этого появляются сервисы, обработчики, таблицы и конкретные шаги реализации.

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

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

При этом бизнесовая формулировка задачи сама по себе не делает задачу атомарной. Даже User Story может скрывать мамонта размером с сервис. Хороший "атом" – это минимальный вертикальный срез, который:

▫️ Даёт наблюдаемый результат.
▫️ Можно проверить и принять.
▫️ Реально завершить за одну короткую итерацию.

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

Не так важно, назовёте вы такой срез фичей, Use Case или User Story. Формула "Как пользователь, я хочу..., чтобы..." помогает сохранить мотивацию, но это только приглашение к разговору, а не магическое заклинание и не замена требованиям. Ориентир должен быть на частую поставку ценного результата, обратную связь и готовность изменить план после получения новых знаний.

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

Такой переход даётся тяжело. Недостаточно научить сотрудников иначе оформлять задачи. Перестроиться должна вся вертикаль: заказчик, бизнес- и системная аналитика, архитектура, разработка и тестирование. Это общий навык, который поначалу замедляет работу, зато постепенно делает задачи понятней, планы – честнее, а автоматизацию с помощью AI – реальней. Ведь AI, как и человек, лучше работает, когда видит не только инструкцию, но и цель с критериями результата.

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

#view
Просмотры: 15
Перейти в пост Открыть в MAX Сообщить о неточности
Невозможность Фишера-Линча-Патерсона

— Вот если бы все связи были бы асинхронными...
— Нет, это не решит проблему.
— Почему?

Действительно, давайте разберемся.

Мне предстояло сделать очередную интеграцию. Требования рядовые: к публичному API обращается конечный пользователь, но обработка запроса происходит с обязательным участием внешней системы – крайне нестабильной и медленной, – от которой нужно дождаться положительный ответ для продолжения действий. При этом важны и атомарность, и производительность...

В этот момент начинается анализ требований и ограничений, в голове перебираются возможные варианты решений: от самых простых до самых сложных. Наш мозг пытается найти компромисс. В мыслях промелькивают ACID, гарантии доставки, transactional outbox, saga, request/response over async и много всего... Ведь никто в здравом уме не хочет включать внешний вызов в транзакцию БД; все хотят делать долгую работу асинхронно. И может возникнуть мысль: "А если бы все связи были асинхронными?!"

Ответ на этот вопрос нашли в уже далёком 1985 три учёных, которые доказали теорему "FLP Impossibility":

В полностью асинхронной распределённой системе, где нет верхней границы на задержку сообщений и скорость процессов, никакой детерминированный протокол консенсуса, рассчитанный хотя бы на один crash-отказ, не может гарантировать, что все исправные процессы примут решение за конечное время. (M.J. Fischer, N.A. Lynch, M.S. Paterson)

Это самый известный, но не единственный результат научного трио. Ключевые статьи прикреплю в виде файлов ниже, а здесь попробуем взять из этой теории практический максимум. Итак, в распределённых системах:

▫️ Нет безусловных гарантий, есть только компромиссы. Узлы не могут гарантированно судить о состоянии друг друга. Ожидая ответ, неясно, существует ли удалённый процесс или он просто работает очень медленно. Поэтому гарантии консенсуса могут быть даны только в условиях принятых предположений.

▫️ Корректность функционирования должна рассматриваться только в контексте предусмотренных уровней прочности, надёжности и устойчивости. Следовательно, задача не имеет надежного решения без дополнительных предположений о вычислительной среде и ограничений на допустимые типы сбоев.

▫️ Частичная синхронность и рандомизация – два классических способа обойти ограничения FLP. Именно поэтому на практике появляются таймауты, heartbeat, retry, jitter, deadline propagation и прочие техники, которые позволяют обнаруживать отсутствие прогресса и обходить последствия сбоев.

Между тем, FLP – это теорема о задаче консенсуса, т.е. когда все участники должны выбрать одно и то же значение. Это в первую очередь задачи, которые решают разработчики распределённых БД, протоколы Paxos/Raft/Zab. А что с этого тем, кто не решает подобные проблемы, а просто пилит микросервисы?

Для простых смертных есть ещё одна полезная эвристика:

В принятой модели отказов приходится выбирать, чем жертвовать: корректностью функционирования (safety) или вычислительным прогрессом (liveness).

▫️ Выбираем корректность. При сбое система останавливается, вместо того чтобы функционировать неправильно. Например, лучше зависший заказ (потеря прогресса), чем двойное списание денег (потеря корректности).

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

➡️ Теперь у нас есть ещё один вариант обоснования архитектурного решения и понимание, что асинхронность не плоха сама по себе, но заставляет явно формулировать предположения о времени и сбоях.

Ссылки
🔗 Impossibility of Distributed Consensus with One Faulty
🔗 Easy Impossibility Proofs for Distributed Consensus Problems

#arch #devops
Просмотры: 35
Перейти в пост Открыть в MAX Сообщить о неточности
Что лучше: поддомен или ограниченный контекст

Думаю, каждый слышал про домены и ограниченные контексты. Но как эти понятия соотносятся друг с другом? Это одно и тоже или нет? Когда использовать одно, а когда другое? Давайте сломаем стереотипы и развеем мифы! 🥷

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

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

1️⃣ Суть контекста

▫️ Поддомены выявляются на основе анализа бизнеса.

▫️ Ограниченные контексты проектируются, исходя из требований и ограничений.

Это значит, что наряду с прочим поддомены задают дополнительный контекст, который должен учитываться при проектировании границ – ограниченных контекстов. Или, говоря проще, первое – это данность, второе – как мы эту данность учитываем при проектировании.

В нашем примере можно выделить два поддомена – основной и вспомогательный:
▫️ Игровой движок – распоряжается ресурсами с учётом механики игры.
▫️ Система учёта – регистрирует изменения ресурсов и строит аналитические срезы.

2️⃣ Ответственность контекста

Ограниченный контекст задаёт границы:

▫️ Единого языка
▫️ Модели решения
▫️ Физические границы (сервис, модуль, пакет)
▫️ Границы владения (исполнитель, команда)

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

Разные модели одного и того же объекта определяют физические границы и, очевидно, границы владения: у контекста должен быть только один владелец.

Нарушение любой границы приведёт к хаосу и конфликтам.

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

3️⃣ Размер контекста

Контекст может охватывать:

▫️ Один поддомен. Часто самый разумный выбор. Модели – раздельные, точные, прагматичные.

▫️ Часть поддомена. Если поддомен большой, его можно разделить на разные контексты, если это способствует эффективному решению разных задач.

▫️ Несколько поддоменов. Небольшие системы или монолиты. Модели – общие, большие, плохо поддерживаемые, провоцирующие конфликты.

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

В нашем примере границы контекстов рационально провести по границам поддоменов. Игровой движок будет в своём контексте, учётная система – в своём. Каждый контекст будет представлен отдельным сервисом.

4️⃣ Взаимодействие контекстов

Сопряжение контекстов – это всегда интеграционный слой с определённым контрактом. Тема требует отдельного разбора, но тут важно ответить, на каком языке будет выражен контракт: в терминах модели какого контекста. Выбор всегда зависит от условий решения.

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

➡️ Итог

Получается, что поддомены и ограниченные контексты совсем не конкурирующие, а ортогональные концепции. Тем не менее, они очень хорошо дополняют друг друга. Надеюсь, что теперь всё встало на свои места. 🐈

#arch #dev
Просмотры: 44
Перейти в пост Открыть в MAX Сообщить о неточности
Тип поддомена и стратегия решения

Обычно DDD воспринимают как высшую математику: всё логично, но непонятно, как применять на практике. Сегодня предлагаю свести теорию с практикой и посмотреть, как определение поддомена определяет стратегию решения. 🎯

На самом деле стратегия не в том, чтобы пилить систему на поддомены; и не в самом факте существования поддомена. Стратегия – в выборе проектных решений, исходя из типа поддомена.

➡️ Проще говоря, правильно определив тип поддомена, сможете легко понять, работаете ли вы над чем-то стоящим или просто тратите время и ресурсы впустую.

Смотрим, как сориентироваться на местности, сделав три простых шага.

1️⃣ Введём понятие типа поддомена:

▫️ Основной (core). Уникальная деятельность компании (не обязательно техническая), определяющая её конкурентные преимущества. Основной домен может не приносить прибыль, но служить основой для её привлечения. Как например, поиск Google служит основой для рекламы – Google Ads.

▫️ Универсальный (generic). Деятельность, которую все компании выполняют или должны выполнять одинаково: бухгалтерский учёт, платежи, аутентификация, авторизация, шифрование, мониторинг и т.п. Сюда относятся готовые, широко используемые и проверенные временем решения. Например, для бухучёта 1С, для мониторинга OpenTelemetry и т.д.

▫️ Вспомогательный (supporting). Поддерживающий слой для основного поддомена. Это то поле, где универсальные решения не подходят или неудобны для ведения бизнеса. Например, административный интерфейс для настройки или поддержки системы.

2️⃣ Определим их свойства:

▫️ Основной – сложный и изменчивый, т.к. иначе не будет конкурентного преимущества.

▫️ Универсальный – сложный и стабильный, т.к. иначе каждый бы делал своё решение.

▫️ Вспомогательный – простой и стабильный, но со специфической бизнес-логикой, т.к. иначе подойдёт универсальное решение.

3️⃣ Выберем стратегию решения:

▫️ Основной – делаем самостоятельно, силами лучших кадров; используем передовые технологии и уникальные алгоритмы.

▫️ Универсальный – используем готовые, проверенные временем решения.

▫️ Вспомогательный – делаем самостоятельно, силами middle-специалистов.

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

И в контексте этого стоит сразу расставить красные флаги:

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

🚩 Сложность основного поддомена не определяет сложность решения. Напротив, сложность должна сводиться к минимуму, например, путем декомпозиции поддомена на более мелкие и делегирования большей части работы готовым решениям.

🚩 Ничего не стоит на месте. Типы поддоменов могут меняться, и это определяется деятельностью компании. Основной поддомен может стать вспомогательным для других; вспомогательный может трансформироваться в универсальное решение, которое начнёт приносить прибыль и станет основным для бизнеса; вспомогательные решения могут/должны заменяться универсальными.

Надеюсь, что этот простой приём поможет расходовать ресурсы более продуктивно. 🐈

#arch #dev
Просмотры: 30
Перейти в пост Открыть в MAX Сообщить о неточности
Контракт ошибок

Как часто мы совершаем ошибки? Постоянно! Что мы делаем в случае неудачи? 🍑 Стремимся её исправить, а если не получилось, решаем, как рассказать об этом заинтересованным лицам. Подбирая нужные слова, оцениваем размер ущерба и возможную реакцию на возникшую ситуацию. Вместе с этим исходный контекст может быть обобщён, изменён или расширен.

Допустим, вы так и не смогли выполнить задачу по интеграции с другой системой из-за недостатка информации. Но руководителю вместо голого факта говорите что-то в стиле: "Я запросил документацию у владельцев системы, они сегодня дадут ответ, и я уточню сроки реализации."

В такой форме мы передаём:

▫️ Контекст – "задача не выполнена"

▫️ Текущее состояние – "запросил документацию, жду ответ"

▫️ Масштаб последствий – "сроки реализации затягиваются"

▫️ Дальнейшие действия – "сегодня уточню сроки"

И это не вежливость, это управление ожиданиями, которое постоянно используется в быту. А в программных системах это называется контрактом ошибок.

Но несмотря на то, что программы ошибаются чаще людей, контракту ошибок уделяется не так много внимания. Возможно, из-за того, что в момент реализации API не было чёткой структуры действий; а возможно, из-за излишней сосредоточенности только на функциональности.

При проектировании API внимание должно быть уделено трём составляющим:

1️⃣ Набор операций

2️⃣ Модель данных

3️⃣ Контракт ошибок

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

К счастью, проектируя современные API, многие стали уделять больше внимания ошибкам и их мониторингу. Однако всё это делается без должного внимания к деталям, а те, что имеются, часто не несут ценности.

Контракт ошибок есть, мониторинг есть, но оба бесполезны.

Почему так происходит? Всё как в обычной жизни: не подумали о реакции пользователя на ошибки.

➡️ Если собираетесь сообщить об ошибке, подумайте, что с ней будет делать пользователь вашего API, у которого гораздо меньше контекстной информации, чем у вас сейчас. Как именно вы хотите повлиять на его поведение?

За каждой ошибкой в любом API должна быть предусмотрена какая-то история по её анализу и обработке. Если такой истории нет, это признак плохого дизайна. Проверить полезность ошибки очень легко:

Может и должен ли пользователь API действовать как-то иначе, чем просто try-catch-log или try-catch-retry?

Если может – отлично, API определяет поведение пользователя; если нет – ошибка ничем не отличается от безликой Internal Server Error. Последнее может быть сигналом, что вам не нужна излишняя детализация в ответе. И это нормально, если всё, что вы ожидаете – это log или retry.

➡️ Излишняя детализация ошибочных ситуаций – это ещё одна ловушка, в которую можно угодить, руководствуясь добрыми намерениями. И чаще всего в эту ловушку попадают аналитики и тестировщики, демонстрируя, что они предусмотрели все возможные варианты использования.

Рассмотрим конкретный пример. Предположим, нужно отменить заявку записи на приём ко врачу. Предполагается, что клиент передает только ID заявки. Операция может завершиться неудачей только по двум причинам: передали несуществующий ID или заявка уже отменена. Для каждого такого случая можно было бы предусмотреть свою ошибку. Но будет ли отличаться поведение пользователя в первом и втором случае? Нет, и более того, в обеих случаях не предполагается retry.

А что, если вероятность передачи несуществующего ID крайне низкая, конкурентность записи высокая, а пользователь работает с API по принципу fire-and-forget? Возможно, что в такой ситуации и ошибку возвращать бессмысленно.

Ошибки – это неотъемлемая часть проектирования контракта взаимодействия, поэтому в центре дизайна должно стоять поведение, а не попытки рассказать, что именно пошло не так.

#view #arch #dev
Просмотры: 24
Перейти в пост Открыть в MAX Сообщить о неточности
Работай с датой и временем правильно!

Можно бесконечно смотреть на три вещи: как горит огонь, течёт вода и как люди пытаются работать с датой и временем. 😃 Но одна из этих вещей мне окончательно надоела, поэтому я решил написать на эту тему целую статью.

Если вы думаете, что знаете про время всё, то я в этом ничуть не сомневаюсь. 😏 Однако, по моим наблюдениям, даже среди технических специалистов, включая опытных разработчиков, достаточно много людей, которые не понимают базовых вещей либо имеют кучу стереотипов, в которые продолжают охотно верить. Это не проблема до тех пор, пока неумелое творчество таких коллег не касается лично вас. Надеюсь, что данная статья, как минимум, поможет вспомнить смешные и не очень истории из жизни или найти для себя что-то новое и незнакомое.

Получилось много, но надеюсь, будет интересно.

🔗 Ссылка на статью

#arch #dev
Просмотры: 23
Перейти в пост Открыть в MAX Сообщить о неточности
System Design: чьё кунг-фу сильней

Мы все в той или иной степени архитекторы. А для архитектора всегда была важна насмотренность и широта знаний. 💪 Но где её получить, сидя на одном проекте долгие годы? 😮‍💨 Как минимум, часть информации можно найти в книгах. Конечно, никто не будет досконально описывать архитектуры реальных систем, но принципы построения больших систем найти можно.

Если цель – расширить кругозор и понять базовое устройство крупных распределённых систем, лучше начать с книг по System Design (Interview). Формат подобных книг позволяет за раз рассмотреть несколько кейсов и увидеть, как теория применяется на практике.

Для обозначенной цели могу порекомендовать две книги:

🗂 System Design Interview - An Insider's Guide, Alex Xu, 320p (System Design. Подготовка к сложному интервью, Алекс Сюй, 304с)

🗂 Acing the System Design Interview, Zhiyong Tan, 472p (System Design: пережить интервью, Чжиюн Тань, 544с)

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

Книга Alex Xu ценна тем, что идёт от простого к сложному. Содержимое предыдущих глав используется в последующих. В итоге получается целостный материал, который будет понятен без особой предварительной подготовки. В каждом кейсе автор четко выдерживает формат повествования, к которому привыкаешь практически сразу. Кейсы описаны кратко, но в то же время достаточно понятно. В конце решения накидываются варианты возможных дополнительных вопросов, но практически не рассматриваются альтернативные архитектуры. Пожалуй, лаконичность и легкость подачи материала – главные драйверы успеха этой книги.

Книга Zhiyong Tan выполнена в похожем стиле, но требует от читателя гораздо больше подготовки. Иначе говоря, новичкам чтение может не принести пользу. В первой части автор заставляет вспомнить минимально необходимый базис, не пытаясь даже объяснить некоторые детали. Если Alex Xu пытается заполнить пробел, то Zhiyong Tan в конце каждой главы даёт ссылки на дальнейшее изучение. В связи с этим по началу не понимаешь, что происходит, но основная задумка в том, чтобы читатель понял, что ещё нужно изучить прежде, чем начинать что-то проектировать или пойти на интервью. Вторая часть посвящена разбору кейсов; и главы также логически взаимосвязаны. Ключевое и самое ценное в повествовании – это рассмотрение нескольких возможных архитектур и векторов развития. С этой целью от начала и до конца каждого кейса накидывается куча вопросов, которые должен задавать архитектор. Вместе с этим идеи некоторых возможных решений формулируются настолько кратко и небрежно, что без наличия опыта понять их будет очень трудно. По сути, книга активно демонстрирует архитектурное мышление и процесс поиска компромиссов.

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

〰️〰️〰️

Кстати, если вы решитесь купить книгу Zhiyong Tan в русском переводе, то сразу скажу, что перевод читается тяжело, а некоторые термины переведены крайне отвратительно. В этом отношении перевод книги Alex Xu выполнен почти идеально.

#view
Просмотры: 21
Перейти в пост Открыть в MAX Сообщить о неточности
Вся лента — после бесплатной регистрации
ВКонтакте Телеграм Одноклассники
Избранное в datool.ru

Следите за каналом в личном кабинете

Зарегистрируйтесь в datool.ru, чтобы добавить канал «Архитектоника в ИТ» в избранное и отслеживать его показатели.

Зарегистрироваться
Для владельцев каналов

Подтвердите свой канал

Войдите или зарегистрируйтесь в datool.ru, затем добавьте нашего бота в канал по инструкции в личном кабинете. После проверки владения замок исчезнет и вам станет доступно управление каналом.

Войти или зарегистрироваться

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти