Архитектура приложений — горячие точки
Раздел:
Programming /
Теория разработки
@
23.09.2008 |
Ключевые слова: архитектура architecture
Автор: J.D. Meier Источник: habrahabr
Как часть нашего проекта, мы свели вместе информацию об общих подходах к разработке архитектуры приложений.
Общие подходы представяют собой набор «горячих точек» (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) — дорогая операция.
- Сохраняйте как можно больше диагностической информации в ваших обработчиках исключений.
|
Ведение логов и мониторинг
|
- Постоянно ведите мониторинг.
- Сделайте логи настраиваемыми.
|
Взаимодействие с пользователем
|
- Проверяйте эффективность работы для разных сценариев.
- Работайте над улучшением времени отклика системы.
- Отталкивайтесь от эффективного дизайна пользовательского интерфейса.
|
Проверка данных
|
- Проверяйте данные на длину, диапазон, формат и тип.
- Ограничивайте вводимые данные и сообщайте об ошибках.
- Обезопасьте вводимые данные.
- Не полагайтесь на проверку на стороне клиента.
|
Поток операций
|
- Определите требования к управлению потоками операций. Если ими должен управлять бизнес-пользователь, то обеспечьте ему понятный интерфейс.
- Определите как будут обрабатываться исключения в потоке операций.
- Когда вы имеете с потоком операций, относящимся к людям, не забывайте о неопределённости человеческой натуры. Нельзя полагаться на то, что какая-то задача будет выполнена в какой-то срок и будет выполнена полностью.
- Используйте интерфейсы служб для работы с внешними провайдерами потоков операций.
- Используйте визуальные редакторы и метаданные для разаботки потоков операций вместо кода, если это возможно.
|
От переводчика: Люблю сжатый аналитический подход, поэтому и перевожу. :) И вообще рекомендую блог автора. Там много приятных для мозга списков и таблиц. Разумные поправки к переводу терминов приветствуются. Обсуждение спорных пунктов — тоже.
Вернуться в раздел:
Programming /
Теория разработки
|