Содержание к диссертации
Введение
1 Проблемы проектирования компонентных распределенных систем управления 6
1.1 Основные понятия компонентных технологий 6
1.2 Общие принципы построения распределенных систем 11
1.3 Синхронное и асинхронное взаимодействие 20
1.4 Транзакции 28
1.5 Проблемы проектирования надежного программного обеспечения 32
2 Современные технологии программирования распределенного программного обеспечения 38
2.1 Технология программирования СОМ+ 38
2.1.1 Не жестко связанные события 42
2.1.2 Компоненты с поддержкой очередей 45
2.1.3 СОМ+ безопасность 48
2.2 Технология программирования .NET 50
2.2.1 Структура .NET Framework 53
2.2.2 Библиотека базовых классов 55
2.2.3 .NET и СОМ-объекты 57
2.2.4 Среда исполнения .NET-программ 58
3 Структуры мультиверсионных моделей 61
3.1 Блоки восстановления 61
3.2 N-версионное программирование 65
3.3 N-версионное программирование с самоконтролем 66
3.4 Блоки восстановления с согласованием 67
3.5 Проблемы мультиверсионного программного обеспечения 68
3.5.1 Разработка мультиверсионного программного обеспечения 69
3.5.2 Алгоритмы выбора вывода 72
3.6 Отказоустойчивость в операционных системах 76
3.7 Выводы 78
4 Многоверсионность данных и управление параллельными транзакциями 80
4.1 Транзакции и параллелизм 80
4.2 Временные метки 91
4.3 Многоверсионный вариант двухфазного протокола синхронизации 93
4.4 Многоверсионный протокол для транзакций, не изменяющих данные 95
4.5 MVSG-планировщики 97
4.6 Проблемы реализации версионных алгоритмов 100
4.7 Выводы 102
5 Модели и алгоритмы анализа надежности программных средств 104
5.1 Модель анализа на этапе дизайна архитектуры ПО 104
5.2 Анализ надежности программного обеспечения на фазе кодирования 108
5.3 Анализ надежности программного обеспечения на фазе тестирования системы 109
5.4 Операционные профили тестирования компонент 111
5.4.1 Оценивание вероятностей сбоя 113
5.4.2 Ведение таблиц параметров профилей 113
5.4.2 Пример применения операционных профилей 114
5.5 Модели надежности объектно-ориентированного программного обеспечения 116
5.5.1 Фаза построения архитектуры объектно-ориентированного программного обеспечения 116
5.5.2 Фаза кодирования 120
5.5.3 Фаза тестирования 120
5.5.4 Оценка параметров надежности 120
5.5.6 Модель оценки транзакционной надежности объектно-ориентированного программного обеспечения 120
Заключение 126
Список использованных источников
- Основные понятия компонентных технологий
- Технология программирования СОМ+
- Блоки восстановления
- Транзакции и параллелизм
Введение к работе
Современная программная индустрия подразумевает огромные тиражи
продуктов среднего качества, имеющих множество недокументированных и, следовательно, неизвестных пользователю, а, возможно, и разработчику свойств; команду разработчиков средней квалификации, кругозор которых ограничен возможностями узкоспециализированных инструментов и технологий; упрощенную систему обучения, ориентированную на быструю подготовку специалистов узкой квалификации; неприхотливость массового пользователя, который имеет неверные ожидания относительно функций и качества приобретаемых программ и связан круговой порукой с разработчиком за счет вовлечения в процесс тестирования.
Исследования последних лет показывают, что качество работы любой системы управления напрямую зависит от надежности и отказоустойчивости программного обеспечения. За прошедшие десятилетия было создано множество методов и моделей обеспечения требуемого уровня надежности программных средств, каждый из которых давал приемлемые результаты для своей уникальной части программных систем, но не являлся универсальным.
Таким образом, учитывая возможности современной программной индустрии и ограничения, накладываемые на системы управления, необходимо выбрать новые методы, которые позволят объективно оценивать надежность будущих систем управления.
Одним из подходов к созданию современных отказоустойчивых систем управления является мультиверсионная методология избыточности. Мультиверсионное программирование позволяет добиться программной избыточности, призванной предупредить случайные сбои. Причем работа системы управления застрахована также и от сбоев, вызванных ошибками, сгенерированными еще во время проектирования и разработки программного обеспечения. Очевидно, что чем больше глубина мультиверсионности, т. е. чем больше число мультиверсий, обеспечивающих исполнение программных
модулей, тем выше вероятность корректного функционирования мультиверсионного программного обеспечения.
Системы управления, разработанные по мультиверсионной методологии, исходят из того, что возникновение сбоя в функционально эквивалентных модулях происходит в различных точках, благодаря чему сбои могут быть обнаружены и исправлены. Мультиверсионная методология основывается на разнообразии входных данных, которое может быть введено в следующих элементах процесса разработки мультиверсионного программного обеспечения:
языки программирования модулей;
алгоритмы решения типовых задач;
средства программирования;
методы тестирования.
Эффективность мультиверсионного подхода заключается в независимости сбоев различных модулей и является одной из основ мультиверсионного программного обеспечения. Если модули работают в едином адресном пространстве памяти, разделяют одни и те же ресурсы операционной системы, то могут возникнуть дополнительные зависимости между модулями мультиверсионного программного обеспечения. Это создает техническую проблему изоляции исполнительного кода версии модулей мультиверсионного программного обеспечения, что позволит повысить отказоустойчивость и транзакционную надежность программного обеспечения
Разработка методов и моделей совместного использования современных технологий, с поддержкой транзакционной модели для отказоустойчивости функционирования распределенного мультиверсионного программного обеспечения представляют собой научную проблему.
Основные понятия компонентных технологий
Понятие программного компонента (software component) является одним из ключевых в современной инженерии программного обеспечения (ПО). Новейшие программные продукты создаются с использованием компонентной или модульной архитектуры, где под компонентом имеется в виду то же, что часто называется программным модулем. Это функционально полный и завершенный элемент структуры системы, определенным образом выделенный среди окружения, решающий некоторые подзадачи в рамках общих задач системы и взаимодействующий с окружением через определенный интерфейс. Такой компонент называется архитектурным компонентом или компонентом архитектуры.
Компоненты архитектуры являются блоками, из которых строится компонентное программное обеспечение. Эти же компоненты имеются в виду, когда говорят о компонентных технологиях, компонентной или компонентно-ориентированной (component based) разработке ПО, компонентах JavaBeans, EJB, CORBA, ActiveX, VBA, COM, DCOM, .NET, Web-службы (web services). Согласно [1], такой компонент представляет собой структурную единицу программной системы, обладающую четко определенным интерфейсом, который полностью описывает ее зависимости от окружения. Такой компонент может быть независимо поставлен или не поставлен, добавлен в состав некоторой системы или удален из нее, в том числе, может включаться в состав систем других поставщиков.
Один такой компонент может также иметь несколько интерфейсов, играя несколько разных ролей в системе. При описании интерфейса компонента важна не только сигнатура операций, которые можно выполнять с его помощью. При этом становится важным то, какие другие компоненты он может задействовать при работе, а также каким ограничениям должны удовлетворять входные данные операций, и какие свойства выполняются для результатов их работы.
Все эти ограничения являются так называемым интерфейсным контрактом или программным контрактом компонента. Интерфейс компонента включает набор операций, которые можно вызвать у любого компонента, реализующего данный интерфейс, и набор операций, которые этот компонент может вызвать в ответ у других компонентов.
Интерфейсный контракт для каждой операции самого компонента или используемой им определяет предусловие и постусловие ее вызова. Предусловие операции должно быть выполнено при ее вызове, иначе корректность результатов не гарантируется. Если эта операция вызывается у компонента, то обязанность позаботиться о выполнении предусловия лежит на клиенте, вызывающем операцию. Если же эта операция вызывается компонентом у другого компонента, он сам обязуется выполнить это предусловие. С постусловием все наоборот — постусловие вызванной у компонента операции должно быть выполнено после ее вызова, и это — обязанность компонента.
Постусловие операции определяет, какие ее результаты считаются корректными. В отношении вызываемых компонентом операций выполнение их постусловий должно гарантироваться теми компонентами, у которых они вызываются, а вызывающий компонент может на них опираться в своей работе.
Пример. Рассмотрим сайт Интернет-магазина. В рамках этого приложения может работать компонент, в чьи обязанности входит вывод списка товаров заданной категории. Одна из его операций принимает на вход название категории, а выдает HTML-страничку в заданном формате, содержащую список всех имеющихся на складе товаров этой категории. Предусловие может состоять в том, что заданная строка действительно является названием категории.
Постусловие требует, чтобы результат операции был правильно построенной HTML-страницей, чтобы ее основное содержимое было таблицей со списком товаров именно указанной категории, название каждого из которых представляло бы собой ссылку, по которой можно попасть на его описание, а в остальном — чтобы эта страница была построена в соответствии с принятым проектом сайта.
Более аккуратно построенный компонент не требовал бы ничего в качестве предусловия (т.е. оно было бы выполнено при любом значении параметра), а в случае некорректного названия категории в качестве результата выдавал бы HTML-страницу с сообщением о неправильном названии категории товаров. При реализации интерфейса предусловия операций могут ослабляться, а постусловия — только усиливаться.
Это значит, что, реализуя данную операцию, некоторый компонент может реализовать ее для более широкого множества входных данных, чем это требуется предусловием, а также может выполнить в результате более строгие ограничения, чем это требуется постусловием. Однако внешним компонентам нельзя опираться на это, пока они работают с исходным интерфейсом — реализация может поменяться.
Точно так же, если интерфейс для своей работы требует наличия в системе других интерфейсов с определенным набором операций, это не означает, что данная реализация этого интерфейса действительно вызывает эти операции.
Компонент в этом смысле — единица развертывания. Он может быть присоединен к остальной системе, когда она уже некоторое время работает, и должен после этого выполнять все свои функции, если в исходной системе уже были все компоненты, от которых он зависит. Он может быть удален из нее.
Естественно, после этого могут перестать работать те компоненты, которые зависят от него. Он может быть встроен в программные продукты третьих партий и распространяться вместе с ними. В то же время никакая его часть не обладает этими свойствами. В идеале такой компонент может быть добавлен или полностью замещен другой реализацией тех же интерфейсов прямо в ходе работы системы, без ее остановки. Хотя и не все разновидности компонентов обладают этим свойством, его наличие признается крайне желательным.
Технология программирования СОМ+
С самого начала технология СОМ разрабатывалась с учетом обеспечения поддержки распределенных сред, т.е. способности клиента создавать объекты на других машинах и вызывать их методы по сети. Эти планы стали реальностью в 1996 году после выпуска распределенной COM (Distributed СОМ — DCOM). DCOM позволяет клиенту создавать и использовать объекты, как на удаленных системах, так и на локальной. Более того, клиент может даже не осознавать различия между этими двумя случаями. Подобно тому, как клиенты СОМ имеют прозрачный доступ к объектам в динамических библиотеках и локальных процессах, DCOM обеспечивает прозрачный доступ к объектам в удаленных процессах. Расширением СОМ-технологии является технология Microsoft Transaction Server (MTS) благодаря которой появилась возможность совместного использования СОМ-объектов многими клиентами, авторизованный доступ к этим объектам, а также при необходимости обработку транзакций этими объектами. Расширенная таким образом технология СОМ получила название СОМ+, структура которой показана на рисунке 2.1. Новая версия СОМ - это совокупность программных средств, обеспечивающих разработку, распространение и функционирование распределенных приложений для сетей Интернет и интранет. В ее состав входят: Программное обеспечение промежуточного уровня, обеспечивающее функционирование объектов транзакций во время выполнения. Утилита MTS Explorer, позволяющая управлять объектами транзакций. Интерфейсы прикладного программирования. Средства управления ресурсами.
Стандартная программная модель приложений, использующих СОМ+, представляет собой трехзвенную архитектуру распределенных приложений, состоящую из серверов, клиентов и ПО промежуточного уровня. При этом бизнес-логика приложения сконцентрирована в объектах транзакций, а ПО промежуточного уровня, управляющее этими объектами, построено с использованием компонентной модели.
Базовая программная модель технологий являются идентичной: компоненты разрабатываются по порядку, сначала описываются интерфейсы, для обеспечения автоматизации реализуется IDispatch, реализуется код для регистрации, т.е. в рамках новой парадигмы нужно делать то же, что делалось и ранее. Однако в дополнение к этому появились новые сервисы, значительно расширяющие возможности приложений.
СОМ был создан как компонентная технология уровня изолированной рабочей станции. Потом, с реализацией распределенного СОМ в NT4 (DCOM), эта технология получила развитие в направлении поддержки удаленных обращений к компонентам. MTS создавался для обеспечения работы серверных компонент и устранения некоторых недостатков DCOM. СОМ+ появился для унификации и объединения COM, DCOM и MTS в согласованную технологию, понятную и удобную для реализации приложений корпоративного уровня.
Приложение СОМ+ является основной единицей для защиты и администрирования компонент. СОМ+ это множество СОМ компонент, которые выполняют согласованные функции. СОМ класс представляет собой именованный набор интерфейсов (один или несколько). СОМ объект - это созданный экземпляр СОМ класса. СОМ компонент - это бинарная единица кода, функцией которого является создание СОМ объекта. Интерфейс - это группа логически взаимосвязанных функций, называемых, методами. Таким образом, можно сказать, что каждый из компонент состоит из интерфейсов, который, в свою очередь, состоит из методов. СОМ класс идентифицируется уникальным идентификатором CLSID, интерфейс - IID.
Инструментарий администрирования сервисов компонент может использоваться для включения новых компонент в распределенное приложение, установки свойств и атрибутов, определяющих их поведение. Создание логических групп компонент в виде СОМ+ приложений позволяет получить следующие преимущества СОМ+: Определение пространства развертывания СОМ компонент Общее конфигурирование СОМ компонент, включая службу безопасности, балансировку загрузки компонент, диспетчеризацию очередей сообщений компонент Разработчик более не беспокоится об обеспечении сохранения атрибутов компонент - это задача операционной системы Компонентные DLL загружаются в процесс по усмотрению разработчика Создание и управление потоками выполнением компонент Осуществление доступа к контексту объекта за ресурсами позволяет автоматически ассоциировать их с контекстом объекта
Разработка СОМ+ приложений включает разработку СОМ компонент, содержащих логику приложения, интеграцию их в СОМ+ приложение и администрирование его при развертывании и поддержке.
Разработка СОМ компонент: Определение СОМ классов и их воплощение Группировка классов в компоненты Определение множества СОМ+ сервисов, необходимых для компоненты Разработка СОМ+ приложения Интеграция компонент в СОМ+ приложение, уже существующее или новое Определение правильного множества атрибутов для каждого класса. Эти атрибуты представляют зависимости компонент от используемых сервисов (транзакции, очереди и т.д.).
Блоки восстановления
Методика Блоков Восстановления ([18, 19]) комбинирует основные идеи метода контрольных точек и рестарта для мультиверсионных компонент программного обеспечения таким образом, что различные версии используются только после того, как обнаруживается ошибка (см. рисунок 3.1).
Контрольные точки определяются перед исполнением версий. Контрольные точки необходимы, чтобы восстановить состояние после того, как версия произведет сбой и не сможет обеспечить корректную начальную точку для следующего компонента. Приемочный тест не должны быть только выходным тестом и может быть осуществлен различными встроенными проверками, чтобы увеличить эффективность обнаружения ошибок. Также, из-за того, что первичная версия будет выполняться успешно в большинстве случаев, альтернативы могут быть разработаны с более низкой производительностью и качеством, в некотором смысле (например, вычисляя значения с меньшей точностью). Подобно методу разнообразия данных, вывод альтернативных версий может быть разработан таким образом, чтобы быть эквивалентным первичному (с определением эквивалентности, зависящей от приложения). Фактическое выполнение множественных версий может быть последовательным или параллельным в зависимости от вычислительных мощностей и требований производительности. Если все альтернативы выдали сбой, компонент должен инициировать исключение, чтобы сообщить остальной части системы об отказе завершения его функции. Следует отметить, что такое возникновение отказа не подразумевает постоянный отказ компонента, он может быть повторно использован после изменений его состояния или ввода. Возможность совпадения отказов является источником больших дискуссий относительно всей технологии отказоустойчивого мультиверсионного программного обеспечения.
Предложены модели восстановления версий после сбоя, которые позволяет реализовать выбранные технологии объектно-ориентированного компонентного программирования.
Предлагается использовать временные состояния версий компонент для восстановления сбойных версий в контрольных точках. Данная схема изображена на рисунке 3.1.1, где СРІ - это контрольные точки. Благодаря такому подходу гибкость построения мультиверсионного ПО значительно увеличивается в отличие от классических методов.
Возможность сериализации объектов из технологии .NET позволяют сериализовать всю версию целиком или только результаты ее работы. В первом случае, появляется возможность вернуться к последнему успешному выполнению версии, сохраненный файл содержит полную информацию необходимую для восстановления предыдущего состояния объекта в памяти. Такой подход удобен для проведения диагностики работы версии, так как в файл сохраняется двоичная копия объекта из памяти. Второй случай, когда при разработке версии заранее задается набор данных, который необходимо сохранить, позволяет использовать результаты состояний разных версий друг для друга, если при разработке были приняты необходимые ограничения к временным состояниям.
Введение состояния версий может использоваться для различных целей, отличных от целей восстановления версий, например отладка версий, что особенно удобно при первом методе, т.к. появляется возможность работать с полной информацией об объекте, измерение производительности, откат действий(транзакций), сбор различной статистической информации о моделируемом или управляемом объекте или процессе и т.п.
При разработке функций временных состояний версий можно получить некоторые вспомогательные функции: - Превентивное тестирование» версий, которые в текущий момент не используются для сравнения их временных состояний. - Сохранять временные состояния версий в хранилище данных и использовать для восстановления сбойных версий. - Перезапустить все версии (может быть полезно, при аппаратных сбоях или при множественных программных сбоях).
Транзакции и параллелизм
Современные СУБД являются многопользовательскими системами, т.е. допускают параллельную одновременную работу большого количества пользователей. При этом пользователи не должны мешать друг другу. Т.к. логической единицей работы для пользователя является транзакция, то работа СУБД должна быть организована так, чтобы у пользователя складывалось впечатление, что их транзакции выполняются независимо от транзакций других пользователей [17].
Простейший и очевидный способ обеспечить такую иллюзию у пользователя состоит в том, чтобы все поступающие транзакции выстраивать в единую очередь и выполнять строго по очереди. Такой способ не годится по очевидным причинам - теряется преимущество параллельной работы. Таким образом, транзакции необходимо выполнять одновременно, но так, чтобы результат был бы такой же, как если бы транзакции выполнялись по очереди. Трудность состоит в том, что если не предпринимать никаких специальных мер, то данные, измененные одним пользователем, могут быть изменены транзакцией другого пользователя раньше, чем закончится транзакция первого пользователя. В результате, в конце транзакции первый пользователь увидит не результаты своей работы, а неизвестно что.
Как отмечалось в предыдущей главе, транзакция рассматривается как последовательность элементарных атомарных операций. Атомарность отдельной элементарной операции состоит в том, что СУБД гарантирует, что, с точки зрения пользователя, будут выполнены два условия: 1. Эта операция будет выполнена целиком или не выполнена вовсе (атомарность - все или ничего). 2. Во время выполнения этой операции не выполняются никакие другие операции других транзакций (строгая очередность элементарных операций).
Например, элементарными операциями транзакции будут считывание страницы данных с диска или запись страницы данных на диск (страница данных - это минимальная единица для дисковых операций СУБД). Условие 2 на самом деле является именно логическим условием, т.к. реально система может выполнять несколько различных элементарных операций в один и тот же момент. Например, данные могут храниться на нескольких физически различных дисках и операции чтения-записи на эти диски могут выполняться одновременно.
Элементарные операции различных транзакций могут выполняться в произвольной очередности (конечно, внутри каждой транзакции последовательность элементарных операций этой транзакции является строго определенной). Например, если есть несколько транзакций, состоящих из последовательности элементарных операций: Т={Ті,Т2,Тз,...,Тп}, Q={QbQ2,Q3,...,Qm}, S={Si,S2,S3,...,Sj}, то реальная последовательность, в которой СУБД выполняет эти транзакции, может быть, например, такой: {Ti,Qi ,T2,S і ,T3,S2,S3,Q2,...}.
Набор из нескольких транзакций, элементарные операции которых чередуются друг с другом, называется смесью транзакций. Последовательность, в которой выполняются элементарные операции заданного набора транзакций, называется графиком запуска набора транзакций. Обеспечение изолированности пользователей, таким образом, сводится к выбору подходящего (в каком-то смысле правильного) графика запуска транзакций. Одновременно с этим график запуска должен быть оптимальным в некотором смысле, например, давать минимальное среднее время выполнения транзакций каждым пользователем. Каким образом транзакции различных пользователей могут мешать друг другу? Различают три основные проблемы параллелизма [17]: Проблема потери результатов обновления. Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание). Проблема несовместимого анализа. Рассмотрим подробно эти проблемы.
Проблема потери результатов обновления. Две транзакции по очереди записывают некоторые данные в одну и ту же строку и фиксируют изменения.
Результат. После окончания обеих транзакций, строка «Р» содержит значение «Рг», занесенное более поздней транзакцией «В». Транзакция «А» ничего не знает о существовании транзакции «В», и естественно ожидает, что в строке «Р» содержится значение «Pi». Таким образом, транзакция «А» потеряла результаты своей работы (таблица 4.1).