Pull to refresh

Архитектура приложений — горячие точки

Reading time 9 min
Views 25K
Original author: J.D. Meier
Как часть нашего проекта, мы свели вместе информацию об общих подходах к разработке архитектуры приложений.

Общие подходы представяют собой набор «горячих точек» (hot spots). Однако это не просто горячие точки. Эти горячие точки преставляют собой ключевые вопросы, проблемы и рекомендации. Все вместе они помогают вырабатывать более эффективные с технической точки зрения архитектуры. Этот список является частью более общей структуры App Arch Meta Frame. Думайте о нём, как о важной ветке большого дерева.

Категории

Следующие категории являются горячими точками в архитектуре приложения:
  • Аутентификация и авторизация (Authentication and Authorization)
  • Кэширование и состояние (Caching and State)
  • Взаимодействие (Communication)
  • Композиция (Composition)
  • Параллельные вычисления и транзакции (Concurrency and Transactions)
  • Управление конфигурацией (Configuration Management)
  • Связанность и сцепление (Coupling and Cohesion)
  • Доступ к данным (Data Access)
  • Работа с исключениями (Exception Management)
  • Ведение логов и мониторинг (Logging and Instrumentation)
  • Взаимодействие с пользователем (User Experience)
  • Проверка данных (Validation)
  • Поток операций (Workflow)

Горячие точки соответствуют разным сквозным функциональностям, использующимся при создании приложений и, соответственно, разным наборам паттернов и практик. Например, Enterprise Library обычно включает блоки, отвечающие за кэширование, управление исключениями, ведение логов, валидацию и т.д. Категориям также соответствуют разнообразные анти-паттерны, самый плохой из которых — это анти-паттерн «переделать заново» («do over»). :)

Ключевые вопросы

Эта таблица перечисляет ключевые вопросы для каждой горячей точки:

Категория
Ключевые вопросы
Аутентификация и авторизация
  • Как хранить идентификационные данные зарегистрированных пользователей?
  • Как аутентифицировать запросы?
  • Как авторизовывать запросы?
  • Как передавать идентификационные данные пользователей между слоями приложения?

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

Взаимодействие
  • Как передавать информацию между слоями приложения?
  • Как совершать асинхронные операции?
  • Как передавать секретные данные?

Композиция
  • Как спроектировать структуру приложения?
  • Как спроектировать слабую связанность между модулями?
  • Как работать с зависимостями в слабосвязанном режиме?

Параллельные вычисления и транзакции
(прим. переводчика): Тут автор продублировал предыдущую категорию. Если ошибка будет исправлена в оригинале, то исправлю и перевод.
Управление конфигурацией
  • Как определить какая информация подлежит конфигурированию?
  • Как определить где и каким образом сохранять конфигурационную информацию?
  • Как работать с секретной информацией?
  • Как работать с конфигурационной информацией в кластере?

Связанность и сцепление
  • Как разделить функцональности?
  • Как структурировать приложение?
  • Как выбрать подходящее разбиение на слои?
  • Как задать границы между частями системы?

Доступ к данным
  • Как управлять соединениями БД?
  • Как управлять исключениями?
  • Как улучшить производительность?
  • Как улучшить управляемость?
  • Как работать с бинарными данными (BLOBs)?
  • Как использовать пейджинг (paging) для записей?
  • Как управлять транзакциями?

Работа с исключениями
  • Как обрабатывать исключения?
  • Как сохранять информацию об исключениях?

Ведение логов и мониторинг
  • Как определить какую информацию писать в лог?
  • Как сделать запись в лог настраиваемой?

Взаимодействие с пользователем
  • Как повысить эффективность выполнения задач?
  • Как улучшить отзывчивость интерфейса?
  • Как улучшить возможности приложения для пользователя?
  • Как улучшить внешний вид приложения?

Проверка данных
  • Как определить где и когда проводить валидацию данных?
  • Как проверять длину, диапазон, формат и тип данных?
  • Как ограничить вводимые данные и сообщать о неправильных значениях?
  • Как обезопасить (sanitize) выводимые данные?

Поток операций
  • Как решать проблемы параллельных вычислений в потоке операций?
  • Как обрабатывать ошибки в потоке операций?
  • Как координировать процессы в потоке операций?


Ключевые проблемы

Эта таблица сводит вместе ключевые проблемы для каждой горячей точки:
Категория
Ключевая проблема
Аутентификация и авторизация
  • Хранение идентификацонных данных в открытом виде в файлах.
  • Передача идентификационных данных в открытом виде по сети.
  • Аккаунты с излишними привилегиями.
  • Долгоживущие сессии.
  • Смешивание персонализации и аутентификации.
  • Использование единственного контроллера доступа (gatekeeper).
  • Отсутствие ограничений на доступ к системным ресурсам для приложения.
  • Отсутствие ограничений на доступ к БД кроме определённых хранимых процедур (stored procedures).
  • Неадекватное разделение прав доступа.

Кэширование и состояние
  • Промахи кэша.
  • Отсутствие устаревания (expiration) данных в кэше.
  • Плохая архитектура кэша.
  • Отсутствие синхронизации кэша, необходимого для хорошего масштабирования системы.

Взаимодействие
  • Повышенный сетевой трафик и задержки из-за «тяжёлых» сообщений межу слоями.
  • Неудачные транспортные протоколы и форматы сообщений.
  • Слишком большие объёмы данных в сетях ограниченной пропускной способности.

Композиция
  • Тесно связанные модули
  • Дублированный код

Параллельные вычисления и транзакции
  • Блокирующие вызовы.
  • Негранулированная блокировка данных (nongranular locks).
  • Неправильная работа с потоками.
  • Слишком долгое удержание блокировки данных.
  • Неправильные уровни изоляции БД.

Управление конфигурацией
  • Небезопасные интерфейсы администрирования.
  • Небезопасные конфигурационные хранилища.
  • Хранение конфигурационных данных в открытом виде.
  • Слишком много администраторов в системе.
  • Слишком много привилегий для аккаунтов служб и процессов.

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

Доступ к данным
  • Использование отдельного логина/пароля для каждого пользователя когда в этом нет необходимости.
  • «Тяжёлые» запросы к БД.
  • Рассеянная по классам бизнес-логика.

Работа с исключениями
  • Оставление системы/приложения в нестабильном состоянии.
  • Открытие секретной информации конечным пользователям.
  • Использование исключений для работы логики.
  • Запись в логи недостаточной информации об исключении.

Ведение логов и мониторинг
  • Отсутствие логов и мониторинга.
  • Слишком высокая детализация логов и мониторинга.
  • Отсутствие настроек логов и мониторинга во время исполнения (run-time).
  • Отстуствие логов для критических бизнес-операций.

Взаимодействие с пользователем
  • Неэффективная поддержка задач пользователя.
  • Плохое время отклика.
  • Игнорирование пользователей с ограниченными возможностями.

Проверка данных
  • Фильтрация ошибочных данных лишь на уровне приложения.
  • Небезопасный вывод данных в HTML.
  • Небезопасное вставление данных в SQL.
  • Проверка данных лишь на стороне пользователя.
  • Использование имён файлов, URLов или имен пользователей для принятия решений насчёт безопасности.

Поток операций
  • Сильная связанность.
  • Негибкие процессы.
  • Проблемы с приоритетами и взаимными блокировками (race and deadlock issues).


Ключевые рекомендации

Эта таблица приводит ключевые рекомендации для каждой горячей точки:
Категория Ключевые рекомендации
Аутентификация и авторизация
  • Подумайте над требованиям к регистрации.
  • Разделите открытые всем и закрытые зоны.
  • Используйте политики блокировки аккаунтов конечных пользователей (например при множественных ошибках в пароле).
  • Поддерживайте настраиваемый срок действия пароля.
  • Обеспечьте возможность отключения (disable) аккаунтов администратором.
  • Не храните пароли.
  • Требуйте «сильных» паролей.
  • Не пересылайте паролей в открытом виде по сети.
  • Защищайте cookies c идентификационными данными.
  • Используйте несколько контроллеров доступа (gatekeepers).
  • Ограничьте доступ пользователей к системным ресурсам.
  • Подумайте над степенью детализации прав доступа.

Кэширование и состояние
  • Старайтесь не кэшировать создаваемые лишь для одного пользователя данные.
  • Не кэшируйте данные, которые должны точно предоставляться пользователю и обновляться в реальном времени.
  • Кэшируйте данные, которые меняются не очень часто или полностью статичны.
  • Не кэшируйте очень «тяжёлые» ресурсы.
  • Кэшируйте данные после преобразований, учитывая актуальность информации, на которой они основаны.
  • Сравните применимость дизайнов с хранением состояния (stateful) и без такового (stateless).
  • Обдумайте варианты хранения состояния.
  • Минимизируйте размер данных в сессии.
  • Освобождайте ресурсы сессии как можно быстрее.
  • Старайтесь не запрашивать данные сессии из бизнес-логики.

Взаимодействие
  • Выберите подходящий механизм удалённого взаимодействия.
  • Делайте компактные и удобные внешние интерфейсы.
  • Подумайте над тем, как передавать данные между слоями.
  • Минимизируйте объём данных, передаваемых по сети.
  • Используйте пакеты задач (batch work) для уменьшения количества вызовов по сети.
  • Избегайте транзакций, работающих между границами частей системы.
  • Обдумайте возможность асинхронного взаимодействия.
  • Изучите возможность использования очередей сообщений.
  • Оцените применимость подхода «выстрелил и забыл».
  • Укорачивайте цепочки обработки вызовов с помощью кэширования. Это улучшит масштабируемость.
  • Переместите асинхронность ближе к пользователю, интерфейсам служб и служебным агентам для обеспечения изоляции сервиса от внешних зависимостей.
  • Если вы вынуждены сделать какую-то функциональность синхронной, то подумайте, можно ли внутри сделать асинхронной её часть.

Композиция
  • Избегайте использования динамических представлений (layouts), которые сложно загружать и поддерживать.
  • Будьте осторожны с зависимостями между компонентами. Используйте паттерны абстракции при первой возможности для уменьшения потенциальных проблем с поддержкой системы в будущем.
  • Постарайтесь использовать шаблоны с возможностью вставки данных (placeholders). Например, используйте паттерн Template View для создания динамических веб-страниц, обеспечивающих повторное использование и единообразие.
  • Расмотрите возможность создания представлений из повторно используемых модулей. Например, используйте паттерн Composite View для создания множества элементарных частей, работающих как готовые модули.
  • Используйте хорошо известные паттерны для создания составных интерфейсов, содержащих отдельные модули пользовательских контролов.
  • Модулям не следует прямо ссылаться друг на друга или на приложение, которое их загружает.
  • Для взаимодействия с другими модулями и самим приложением надо использовать службы.
  • Модули не должны отвечать за управление своими зависимостями.
  • Желательно поддерживать добавление и удаление модулей как плагинов.

Параллельные вычисления и транзакции
  • Относитесь к потоку (thread) как общему ресурсу.
  • Создавайте пулы общих ресурсов или ресурсов, которых слишком мало.
  • Запрашивайте ресурс как можно позднее, освобождайте как можно раньше.
  • Изучите эффективность создания и уничтожения объектов.
  • Рассмотрите управление пропускной способностью ресурсов.
  • Снижайте возможные задержки путём минимизации времени блокировки ресурса.
  • Соблюдайте баланс между высокоуровневыми (coarse) и низкоуровневыми (fine) блокировками.
  • Выберите подходящий уровень изоляции.
  • Избегайте выполняющихся долго атомарных транзакций.

Управление конфигурацией
  • Защищайте интерфейсы администрирования системы.
  • Защищайте своё конфигурационное хранилище.
  • Разграничивайте административные полномочия.
  • Используйте минимально возможноые привилегии для аккаунтов процессов и служб.

Связанность и сцепление
  • Разбейте приложение на логические слои (layers/tiers).
  • Правильно выберите расположение для частей приложения в зависимости от требований к надёжности, производительности и масштабируемости.
  • С самого начала проектируйте систему со слабой связанностью.
  • Проектируйте систему с сильным сцеплением.
  • Используйте раннее связывание (early binding) где это возможно.
  • Оцените сходство ресурсов (resource affinity).

Доступ к данным
  • Если ваше приложение использует единственную БД, то используйте специализированный провайдер вместо универсального для большего быстродействия.
  • Если вы поддерживаете несколько видов БД, то вам необходим специальный уровень абстракции, который можно легко настроить под конкретное окружение.
  • Попробуйте управлять пропускной способностью ресурсов.
  • Изучите передачу в БД идентификаторов пользователей.
  • Разделяйте запросы «только для чтения» и транзакционные.
  • Не возвращайте данные, которые не будут использоваться.

Работа с исключениями
  • Не показывайте пользователям данные, которые раскрывают внутренности системы.
  • Не используйте исключения для управления потоком выполнения приложения.
  • Используйте коды ошибок вместо исключений, где это возможно.
  • Не перехватывайте исключения, которые вы не можете обработать.
  • Учтите, что повторное бросание исключения (rethrowing) — дорогая операция.
  • Сохраняйте как можно больше диагностической информации в ваших обработчиках исключений.

Ведение логов и мониторинг
  • Постоянно ведите мониторинг.
  • Сделайте логи настраиваемыми.

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

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

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


От переводчика: Люблю сжатый аналитический подход, поэтому и перевожу. :) И вообще рекомендую блог автора. Там много приятных для мозга списков и таблиц. Разумные поправки к переводу терминов приветствуются. Обсуждение спорных пунктов — тоже.
Tags:
Hubs:
+85
Comments 31
Comments Comments 31

Articles