Asp построение в архитектуре клиент сервер


Содержание

Архитектура ASP.NET MVC 5

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

История создания MVC

Термин используется с конца 70-х гг. прошлого столетия. Этот шаблон происходит из проекта Smalltalk, выполнявшегося в Xerox PARC, где он был задуман как способ организации ранних приложений с графическим пользовательским интерфейсом. Некоторые нюансы первоначального шаблона MVC были связаны с концепциями, специфичными для Smalltalk, такими как экраны и инструменты, но более широкие понятия по-прежнему применимы к приложениям — и особенно хорошо они подходят для веб-приложений.

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

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

Появление платформы Ruby on Rails привело к возобновлению всеобщего интереса к MVC, и он остается шаблоном реализации архитектуры MVC. С тех пор появилось много других инфраструктур MVC, и все они демонстрировали преимущества архитектуры MVC — разумеется, это относится и к ASP.NET MVC.

Особенности архитектурного шаблона MVC

Если оперировать высокоуровневыми понятиями, то архитектурный шаблон MVC означает, что приложение MVC будет разделено, по крайней мере, на три части, которые описаны ниже:

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

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

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

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

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

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

Каждая часть архитектуры MVC является четко определенной и самодостаточной — это то, что называется разделением ответственности. Логика, которая манипулирует данными в модели, содержится только в модели, логика, отображающая данные — только в представлении, а код, который обрабатывает запросы и ввод пользователей — только в контроллере. При четком разграничении всех частей приложение будет легче сопровождать и расширять в течение его срока существования, независимо от того, насколько большим оно станет.

Модель предметной области

Наиболее важной частью приложения MVC является модель предметной области. Эта модель создается за счет определения реальных объектов, операций и правил, существующих в данной отрасли или роде деятельности, которые должно поддерживать приложение; такая совокупность и называется предметной областью.

После этого создается программное представление предметной области — модель предметной области. Для целей ASP.NET MVC Framework модель предметной области — это набор типов C# (классов, структур и т.д.), которые все вместе называются типами предметной области. Операции из предметной области представляются методами, определенными в типах предметной области, а правила предметной области выражаются логикой, заключенной внутри этих методов или путем применения атрибутов C#.

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

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

Распространенный способ отделения модели предметной области от остальных частей приложения ASP.NET MVC предусматривает помещение модели в отдельную сборку C#. Такой подход позволяет создавать ссылки на модель предметной области из других частей приложения, но не будет гарантировать отсутствие каких-либо ссылок в обратном направлении. Это особенно полезно в крупномасштабных проектах.

Реализация MVC в ASP.NET

В инфраструктуре MVC контроллеры — это классы C#, обычно производные от класса System.Web.Mvc.Controller. Каждый открытый метод в классе, производном от Controller, является методом действия который посредством системы маршрутизации ASP.NET ассоциируется с конфигурируемым URL. Когда запрос отправляется по URL, связанному с методом действия, операторы в классе контроллера выполняются, чтобы провести некоторую операцию над моделью предметной области и затем выбрать представление для отображения клиенту.

Взаимодействия между контроллером, моделью и представлением показаны на рисунке ниже:

В инфраструктуре ASP.NET MVC Framework используется механизм визуализации — компонент, отвечающий за обработку представления с целью генерации ответа для браузера. В ранних версиях MVC применялся стандартный механизм визуализации ASP.NET, который обрабатывал ASPX-страницы с использованием модернизированной версии синтаксиса разметки Web Forms. В MVC 3 появился механизм визуализации Razor, усовершенствованный в версии MVC 4 (и оставшийся неизменным в версии MVC 5), в котором применяется совершенно другой синтаксис.

Среда Visual Studio обеспечивает поддержку средства IntelliSense для механизма Razor, упрощая внедрение и ответ на данные представления, передаваемые контроллером.

Инфраструктура ASP.NET MVC не налагает никаких ограничений на реализацию модели предметной области. Модель можно создать с помощью обычных объектов C# и реализовать постоянство с применением любой базы данных, инфраструктуры объектно-реляционного отображения или другого инструмента работы с данными, поддерживаемого .NET.

Сравнение MVC с другими шаблонами

Разумеется, MVC — далеко не единственный архитектурный шаблон программного обеспечения. Существует множество других шаблонов подобного рода, и некоторые из них являются или, во всяком случае, были чрезвычайно популярными. О шаблоне MVC можно узнать много интересного, сравнивая его с альтернативами. В последующих разделах будут кратко описаны разные подходы к структурированию приложения и приведено их сравнение с MVC. Некоторые шаблоны являются близкими вариациями на тему MVC, в то время как другие совершенно отличаются.

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

Шаблон интеллектуального пользовательского интерфейса

Одним из наиболее распространенных шаблонов проектирования является . Большинству программистов на том или ином этапе своей профессиональной деятельности приходилось создавать приложение с интеллектуальным пользовательским интерфейсом. Если вы использовали Windows Forms, WPF или ASP.NET Web Forms, то сказанное относится и к вам.

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

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

Интеллектуальные пользовательские интерфейсы идеальны для простых проектов т.к. позволяют добиться неплохих результатов достаточно быстро (по сравнению с разработкой MVC, которая требует определенной предварительной подготовки и начальных затрат).

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

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

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

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

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

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

Наибольшая слабость приложений с интеллектуальным пользовательским интерфейсом — неэффективность сопровождения — не проявляется при мелких объемах разработки. Если вы создаете несложный инструмент для небольшой аудитории, то приложение с интеллектуальным пользовательским интерфейсом может оказаться идеальным решением. Просто при этом не гарантируется увеличение сложности, поддерживаемое приложением MVC.

Архитектура «модель-представление»

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

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

Архитектура «модель-представление» — это значительное усовершенствование по сравнению с монолитным шаблоном интеллектуального пользовательского интерфейса.

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

Классическая трехуровневая архитектура

Чтобы решить проблемы, присущие архитектуре «модель-представление», трехслойная или трехуровневая модель отделяет код сохранения данных от модели предметной области и помещает его в новый компонент, который называется . Эта архитектура показана на рисунке ниже:

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

Кроме того, ценой некоторых усилий уровень DAL может быть создан так, чтобы модульное тестирование проводилось сравнительно просто. Можно заметить очевидное сходство между классическим трехуровневым приложением и архитектурой MVC. Различие состоит в том, что когда уровень пользовательского интерфейса непосредственно связан с инфраструктурой графического пользовательского интерфейса типа «щелчок-событие» (такой как WPF или ASP.NET Web Forms), выполнение автоматизированных модульных тестов становится практически невозможным. А поскольку часть пользовательского интерфейса трехуровневого приложения может быть сложной, останется много кода, не поддающегося серьезному тестированию.

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

Создание слабо связанных компонентов

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

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

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

Тогда любой другой компонент приложения, которому требуется отправить сообщение электронной почты — например, вспомогательный класс сброса пароля PasswordResetHelper — может отправить сообщение, обращаясь только к методам этого интерфейса. Как видно на рисунке ниже, никакой прямой зависимости между PasswordResetHelper и MyEmailSender не существует.

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

Использование внедрения зависимостей

Интерфейсы помогают разъединять компоненты, но мы по-прежнему сталкиваемся с проблемой: язык C# не предоставляет встроенного способа для легкого создания объектов, которые реализуют интерфейсы, кроме создания экземпляра конкретного компонента с помощью ключевого слова new. В результате получается код, подобный приведенному ниже:

Это нарушает цель, заключающуюся в наличии возможности замены MyEmailSender без изменения вспомогательного класса PasswordResetHelper, и означает, что пройдена только часть пути к созданию слабо связанных компонентов. Класс PasswordResetHelper конфигурирует и отправляет сообщения электронной почты через интерфейс IEmailSender, но чтобы создать объект, который реализует этот интерфейс ему нужно создать экземпляр MyEmailSender. Мы еще больше ухудшили ситуацию, поскольку теперь PasswordResetHelper зависит от класса MyEmailSender и от интерфейса IEmailSender:

Нам требуется способ получения объектов, которые реализуют данный интерфейс без необходимости в непосредственном создании объекта. Решение этой проблемы называется или .

DI — это шаблон проектирования, дополняющий процесс слабой связи. Приведенное далее описание внедрения зависимостей может показаться не совсем понятным, но поверьте — это важная концепция, которая является центральной для эффективной разработки приложений MVC и может вызывать немало путаницы.

Разрыв и объявление зависимостей

Шаблон DI состоит из двух частей. Для начала мы удаляем из компонента — в этом случае PasswordResetHelper — любые зависимости от конкретных классов. Это делается путем создания конструктора класса, который принимает реализации требуемых интерфейсов в качестве аргументов, как показано ниже:

Говорят, что конструктор класса PasswordResetHelper теперь объявляет зависимость от интерфейса IEmailSender, т.е. он не может быть создан и использоваться, пока не получит объект, который реализует интерфейс IEmailSender. В объявлении своей зависимости класс PasswordResetHelper больше не содержит каких-либо сведений о классе MyEmailSender, а зависит только от интерфейса IEmailSender. Выражаясь кратко, класс PasswordResetHelper больше ничего не знает и не заботится о том, как реализован интерфейс IEmailSender.

Внедрение зависимостей

Второй частью шаблона DI является внедрение зависимостей, объявленных классом PasswordResetHelper, когда создаются его экземпляры, отсюда и термин — внедрение зависимостей.

Все это на самом деле означает, что нужно решить, какой класс, реализующий интерфейс IEmailSender, будет использоваться, создать объект этого класса и затем передать готовый объект в качестве аргумента конструктору PasswordResetHelper.

Класс PasswordResetHelper объявляет свои зависимости в собственном конструкторе. Такой подход называется внедрением через конструктор. Зависимости можно было бы также объявить через открытое свойство — этот способ известен как внедрение через установщик.

Зависимости внедряются в PasswordResetHelper во время выполнения. Другими словами, экземпляр некоторого класса, реализующего интерфейс IEmailSender, будет создан и передан конструктору класса PasswordResetHelper во время создания его экземпляра. На этапе компиляции больше не существует никакой зависимости между PasswordResetHelper и любым классом, реализующим интерфейсы, от которых он зависит.

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

Использование контейнера внедрения зависимостей

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

Ответ заключается в использовании контейнера внедрения зависимостей, который также называют контейнером инверсии управления (inversion of control — IoC). Он представляет собой компонент, действующий в качестве посредника между зависимостями, которые объявляет класс вроде PasswordResetHelper, и классами, которые могут применяться для распознавания этих зависимостей, такими как MyEmailSender.

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

Когда внутри приложения нужен объект PasswordResetHelper, его создание запрашивается у контейнера DI. Контейнеру DI известно, что класс PasswordResetHelper объявляет зависимость от интерфейса IEmailSender и что в качестве реализации этого интерфейса указан класс MyEmailSender. Контейнер DI объединяет эти две порции информации, создает объект MyEmailSender и затем применяет его как аргумент при создании объекта PasswordResetHelper, с которым впоследствии можно работать в приложении.

Важно отметить, что мы больше не создаем объекты в приложении самостоятельно с помощью ключевого слова new. Вместо этого мы обращаемся к контейнеру DI и запрашиваем необходимые объекты. Привыкание к такому подходу может занять некоторое время у новичков в DI, но, как вы увидите, инфраструктура MVC Framework предлагает ряд средств, помогающих упростить данный процесс.

Контейнер DI не придется создавать самостоятельно — доступно несколько прекрасных реализаций с открытым исходным кодом и свободно лицензируемых реализаций. Одной из них является реализация Ninject.

Роль контейнера DI может казаться простой и тривиальной, но на самом деле это не так. Хороший контейнер DI, такой как Ninject, обладает рядом удобных функциональных возможностей:

Распознавание цепочки зависимостей

В случае запроса компонента, который имеет собственные зависимости (например, параметры конструктора), контейнер удовлетворит и эти зависимости. Таким образом, если конструктор класса MyEmailSender требует реализацию интерфейса INetworkTransport, то контейнер DI создаст экземпляр стандартной реализации этого интерфейса, передаст ее конструктору MyEmailSender и возвратит результат в виде стандартной реализации IEmailSender.

Управление жизненным циклом объектов

Если компонент запрашивается более одного раза, должен ли каждый раз выдаваться один и тот же или совершенно новый экземпляр? Хороший контейнер DI позволяет конфигурировать жизненный цикл компонента, предоставляя возможность выбора из заранее определенных вариантов: единственный экземпляр (один и тот же экземпляр во всех случаях), кратковременный экземпляр (новый экземпляр в каждом случае), экземпляр на поток, экземпляр на HTTP-запрос, экземпляр из пула и т.д.

Конфигурирование значений параметров конструктора

Если реализация интерфейса INetworkTransport требует, к примеру, строку по имени serverName, должна существовать возможность установки ее значения в конфигурации контейнера DI. Это грубая, но простая система конфигурирования, которая избавляет код от необходимости передавать строки подключения, адреса серверов и т.п.

Написание собственного контейнера DI — великолепный способ понять, каким образом C# и .NET обрабатывает типы и рефлексию, и я рекомендую заняться таким проектом в дождливые выходные. Однако не поддавайтесь соблазну развертывать свой код в реальном проекте. Создание надежного, устойчивого и высокопроизводительного контейнера DI сопряжено с трудностями и для применения вы должны отдать предпочтение испытанному и протестированному пакету. Мне нравится Ninject, но есть множество других доступных пакетов, поэтому вы наверняка найдете такой, который окажется подходящим для вашего стиля разработки.

работа Построение веб-приложения на основе asp. Net и архитектуры сервера iis 0 (стр. 1 из 3)

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

«ТЮМЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»

ИНСТИТУТ МАТЕМАТИКИ И КОМПЬЮТЕРНЫХ НАУК

КАФЕДРА ИНФОРМАЦИОННОЙ БЕЗОПАСНОСТИ

Построение веб-приложения на основе ASP.NET и архитектуры сервера IIS 7.0

Выполнил: студент 367 гр.

Введение

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

А что такое интернет без веб страниц и, соответственно, веб серверов?

Сейчас на рынке можно достаточно большое количество самых разных веб серверов. Один из наиболее распространенных – это Internet Information Server корпорации Microsoft. Учитывая последние тенденции к комплексным решениям Microsoft выпустила IIS 7.0, дающий разработчикам и администраторам новые возможности при создании и управлении сайтами.

В своей работе я ознакомился с новыми возможностями и применил их на практике.

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

Задачи:

1. Изучить новые возможности IIS 7.0

2. Познакомится с ASP.NET

3. Написать модуль аутентификации

Теоретическая часть

Безопасность в сети необходима, особенно если дело касается денег. Злоумышленники прибегнут к всевозможным ухищрениям лишь бы добраться до номера вашего банковского счета, логина и пароля в интернет-магазине. Данный проект написан на C# с применением технологии ASP.NET неслучайно. Существует множество готовых решений и предусмотренных классов для обеспечения безопасности соединения. Microsoft предлагает комплексные решения для многих задач. Продукты этой фирмы используются почти всеми, как в корпоративной сети, так и в обычной жизни. Интересующая нас задача — это создание и сопровождение полноценных защищенных веб приложений, таких как интернет магазин например.

Для создания безопасного веб-приложения необходимо полное понимание слабых мест в системе безопасности. Также необходимо ознакомиться с функциями обеспечения безопасности Windows, .NET Framework и ASP.NET. И, наконец, очень важно понимать способы использования этих функций безопасности для борьбы с угрозами.

Давайте рассмотрим поближе систему безопасности ASP.NET

Чтобы обеспечить безопасность веб-приложений, ASP.NET используется совместно с Microsoft .NET Framework и службами Microsoft Internet Information Services (IIS). Для создания безопасного приложения ASP.NET следует выполнить две основные функции:

· Проверка подлинности (Приложение получает от пользователя учетные данные (различные формы идентификации, такие как имя и пароль) и сравнивает их с данными авторитетного источника.)

· Авторизация (Ограничивает право доступа, предоставляя определенные разрешения или отказывая в них удостоверенной личности)

ASP.NET в сочетании со службами Microsoft Internet Information Services (IIS) может выполнять проверку подлинности учетных данных пользователя, например имен и паролей, используя любой из перечисленных ниже методов проверки подлинности:

· Windows: стандартная, шифрованная или встроенная проверка подлинности Windows (NTLM или Kerberos).

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

· Проверка подлинности с помощью сертификатов клиента.

Рассмотрим Архитектуру безопасности ASP.NET

Рис.1 Архитектура безопасности ASP.NET

Как показано на рисунке, все веб-клиенты взаимодействуют с приложениями ASP.NET с помощью служб IIS. При необходимости IIS проверяет подлинность запроса и затем определяет местонахождение запрошенного ресурса (например, приложение ASP.NET). Если клиент авторизован, ему предоставляется доступ к этому ресурсу.

Во время выполнения приложение ASP.NET может использовать встроенные средства безопасности ASP.NET. Кроме того, в приложении ASP.NET могут использоваться средства безопасности платформы .NET Framework.

Два стандартных стандартных сценария обеспечения безопасности: олицетворение(проверка подлинности Windows) и проверки подлинности с помощью форм с использованием файлов «cookies».

Олицетворение

Рис.2 Олицетворение. На рисунке показана следующая последовательность событий:

1. Запрос поступает в службы IIS от клиента сети.

2. Службы IIS проверяют подлинность клиента, используя стандартную, шифрованную или встроенную безопасность Windows (NTLM или Kerberos).

3. Если клиент проходит проверку подлинности, службы IIS передают удостоверенный запрос в ASP.NET.

4. Приложение ASP.NET олицетворяет клиент, выполняющий запрос, используя лексему доступа, переданную из IIS, и использует разрешения NTFS-файла для предоставления доступа к ресурсам. Приложение ASP.NET должно только проверить, что в файле конфигурации ASP.NET для олицетворения задано значение true ; код безопасности для ASP.NET писать не требуется. Если олицетворение не включено, приложение запускается с удостоверением процесса ASP.NET. Для Microsoft Windows 2000 Server и Windows XP Professional удостоверением по умолчанию является локальная учетная запись с именем ASPNET, которая создается автоматически при установке ASP.NET. Для Microsoft Windows Server 2003 удостоверением по умолчанию является удостоверение пула приложений для приложения IIS (по умолчанию учетная запись NETWORK SERVICE).

5. Если доступ разрешен, приложение ASP.NET возвращает запрошенный ресурс через IIS.

Проверка подлинности с помощью форм

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

Рис.3 Проверка подлинности форм. На рисунке показана следующая последовательность событий:


1. Пользователь создает запрос на защищенный ресурс.

2. Службы IIS получают запрос, и так как IIS разрешают анонимный доступ, они не выполняют никакой проверки подлинности пользователя и передают запрос приложению ASP.NET.

3. Так как ASP.NET использует режим поверки подлинности с помощью форм, приложение ASP.NET проверяет билет проверки подлинности на основе форм для запроса (отдельный файл «cookie»). Если к запросу не приложен билет проверки подлинности, ASP.NET перенаправляет запрос на страницу входа в систему, указанную в файле конфигурации приложения. На странице входа в систему пользователь вводит необходимые учетные данные, обычно имя и пароль. Код приложения проверяет учетные данные, чтобы подтвердить их подлинность. Если учетные данные проходят проверке подлинности, код приложения вкладывает билет проверки подлинности в ответ, который представляет учетные данные пользователя. (Пароль не включается). Если проверка подлинности не пройдена, ответ возвращается с сообщением об отказе в доступе, либо форма входа в систему представляется повторно.Выпущенный билет проверки подлинности включается в следующий запрос к приложению ASP.NET. ASP.NET проверяет допустимость использования билетом проверки подлинности сообщения (MAC).

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

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

IIS 7.0 Особенности

В основе выпуска IIS 7.0 лежит полностью модульный веб-сервер, включающий более 40 компонентов, которые можно объединять в компактные веб-серверы, оптимизированные для необходимой роли в топологии приложения. Эти компоненты создаются на основе нового слоя расширяемости, что позволяет разработчикам расширять или замещать практически любую функцию сервера в машинном коде или с помощью Microsoft® .NET Framework. IIS 7.0 предлагает расширяемость компонентов этапа выполнения, управления и рабочих компонентов, облегчая создание комплексных решений в соответствии с конкретными потребностями. На базе основной платформы IIS 7.0 берется за решение многих проблем, связанных с управляемостью и эксплуатацией сервера. Он обладает принципиально новой системой настройки, обеспечивающей полностью делегированное управление узлами и, в конечном итоге, делающей реальностью развертывание веб-приложений с использованием xcopy. Новые интерфейсы API для целей управления и диагностические компоненты делают процедуры развертывания, администрирования и устранения неполадок сервера значительно проще и удобнее, чем когда-либо прежде.

Архитектура приложений

Onion-архитектура. Часть 1

Термин «Onion Architecture» («луковая» архитектура) был предложен Джеффри Палермо (Jeffrey Palermo) еще в 2008 году. Спустя годы данная концепция стала довольно популярной и является одной из наиболее применяемых типов архитектуры при построении приложения на ASP.NET.

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

Количество уровней может отличаться, но в центре всегда находится модель домена (Domain Model), то есть те классы моделей, которые используются в приложении и объекты которых хранятся в базе данных:

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

Внешний уровень представляет такие компоненты, которые очень часто изменяются. Обычно внешний уровень образуют пользовательский интерфейс, тесты, какие-то вспомогательные классы инфраструктуры приложения. К этому уровню также относятся конкретные реализации интерфейсов, объявленных на нижележащих уровнях. Например, реализация интерфейса репозитория, который объявлен на уровне Domain Services. Вообще все внутрение уровни, которые можно объединить в Application Core, определяют только интерфейсы, а конкретная реализация этих интерфейсов располагается на внешнем уровне.

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

Для более подробного рассмотрения данного типа архитектуры создадим обычный проект ASP.NET MVC 5, который будет называться OnionApp.

Пока это монолитное приложение, в котором весь код размещен в одном проекте. Теперь добавим в решение (не в проект) новую папку. Назовем ее Domain . Затем добавим в папку новый проект. В качестве типа проекта выберем тип Class Library , а в качестве его названия укажем OnionApp.Domain.Core :

Добавим в новый проект класс, представляющий книгу, который и будут представлять Domain Model:

Затем добавим в папку Domain новый проект также по типу >OnionApp.Domain.Interfaces . Затем добавим в этот проект ссылку на вышеопределенный проект OnionApp.Domain.Core и также добавим новый интерфейса:

Этот интерфейс и составляет уровень Domain Services и зависит от уровня Domain Model.

И на данный момент проекты выглядят так:

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

На выше представленной схеме между внешним уровнем и уровнем Domain Services есть еще уровень API или интерфейсов бизнес-логики приложения — уровень Application Services. Этот уровень может включать интерфейсы вспомогательных классов. Например, покупка книги может представлять собой объект, который в зависимости от способа оплата (наличкой, через кредитную карту, через электронные деньги) может включать тот или иной функционал. И, возможно, было бы неплохо определить общий интерфейс покупки, а в зависимости от типа магазина использовать его конкретную реализацию. Поэтому добавим в решение новую папку, которую назовем Services . В эту папку добавим новый проект по типу >OnionApp.Services.Interfaces

И добавим в этот проект интерфейс IOrder:

Данный проект также имеет зависимость от классов проекта OnionApp.Domain.Core . А интерфейс IOrder, представляющий процесс покупки и оформления заказа, использует эти классы в методе MakeOrder() . Предполагается, что в метод передается объект купленной книги.

Теперь перейдем к созданию внешнего уровня, который и будет реализовывать данные интерфейсы. Для этого добавим в решение папку Infrastructure и затем в нее добавим новый проект по типу >OnionApp.Infrastructure.Data .

Илон Маск рекомендует:  InputQuery - Функция Delphi

Данный проект будет реализовывать интерфейсы, объявленные на нижних уровнях, и связывать их с хранилищем данных. В качестве хранилища данных будет использоваться бд MS SQL Server, с которой мы будем взаимодействовать через Entity Framework. Поэтому добавим в этот проект через nuGet все пакеты Entity Framework. Также добавим в проект ссылки на проекты OnionApp.Domain.Core и OnionApp.Domain.Interfaces.

После этого добавим в проект новый класс OrderContext :

Также добавим класс репозитория BookRepository:

Клиент-серверная архитектура: особенности взаимодействия

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

Архитектура «Клиент-Сервер» представляет собой взаимодействие структурных компонентов в сети на основе определенных принципов организации данной сети, где структурными компонентами являются сервер и узлы-поставщики определенных специализированных функций (сервисов), а также клиенты, которые пользуются данным сервисом. Специфические функции принято делить на три группы на основе решения определенных задач:

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

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

Клиент-серверная архитектура наиболее часто используется для создания корпоративных баз данных, в которых информация не только хранится, но и периодически поддается обработке различными методами. Именно база данных является главным элементом любой корпоративной информационной системы, а на сервере располагается ядро этой базы. Так, на сервере происходят наиболее сложные операции, касающиеся ввода, хранения, обработки и модификации данных. Когда пользователь (клиент) обращается к базе данных (серверу), происходит обработка запроса: непосредственно обращение к базе данных и возврат ответа (результата обработки). Результат обработки – это сообщение сети об успешном проведении операции или ошибке. Серверные компьютеры могут обрабатывать одновременно обращение нескольких клиентов к одному и тому же файлу. Такая работа и передача данных по сети позволяет ускорить работу используемых приложений.

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

Архитектура клиент-сервер или Web: выбор разработчика

Везет разработчикам! Им редко приходится иметь дело с теми программными продуктами, которые они создают. Даже если, принимая очередное решение, разработчик исполнен благих намерений, это отнюдь не гарантирует продуктивной работы пользователей и администраторов с его приложением. В последнее время среди наиболее важных вопросов создания сетевых приложений появился еще один: какую выбрать архитектуру — клиент-серверную или основанную на службе Web?

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

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

Клиент-сервер и Web: рассмотрим поближе

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

Дело осложняется еще и тем, что довольно трудно дать точное определение двум рассматриваемым архитектурным подходам. В классической архитектуре клиент-сервер клиентская часть представлена так называемым «толстым» клиентом, т. е. приложением, разработанным с помощью пакета типа Visual Basic или Delphi . Свое «прозвище» он получил в связи с тем, что помимо уровня представления информации содержит еще и бизнес-логику прикладной задачи. Такой клиент работает не только с реляционной базой данных, но и с файл-сервером. Стандартное Web-приложение, как правило, используется лишь для представления данных. Вся бизнес-логика в этом случае выполняется на сервере приложений, который и обращается к СУБД.

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

Исследование производительности

Для сравнительной оценки производительности этих двух подходов мы засекали время реакции пользовательского интерфейса, отражающего работу бизнес-логики сначала на клиентской стороне (при тестировании «толстого» клиента), а потом и на серверной, причем во втором случае приложения запускались на нескольких машинах.

Заложенная в программу бизнес-логика состояла в основном из SQL-запросов, и ее главной целью было просто загрузить процессор машины. Программы на «толстых» клиентах содержали как прикладную часть, так и функции управления пользовательским интерфейсом, например ввод и редактирование данных. Бизнес-логика, работавшая на серверах приложений, была создана преимущественно с помощью программного интерфейса ISAPI (Internet Server Application Programming Interface) фирмы Microsoft и содержала вызовы функций динамических библиотек, в частности отвечающих за формирования страниц HTML. Для доступа к таблицам базы данных обе версии приложений — и клиент-серверная и Web — использовали интерфейс ODBC (Open Database Connectivity).

В процессе запуска наших «доморощенных» приложений мы отметили, что динамические библиотеки, написанные на Delphi , работают быстрее DLL, созданных с помощью Visual Basic. И вообще, производительность Delphi нас приятно удивила. Дело в том, что мы использовали специальную библиотеку WebBridge фирмы Borland International, позволяющую абстрагироваться от конкретного способа взаимодействия с Web-сервером, будь то интерфейс ISAPI или NSAPI (Netscape Application Programming Interface) фирмы Netscape Communications.

У нас не было времени оценить технологию реализации бизнес-логики в виде хранимых процедур, т. е. кода, который запускается непосредственно на компьютере сервера базы данных. Однако перенос бизнес-логики в сетевой среде на процессор компьютера СУБД способен вызвать дополнительные проблемы при увеличении интенсивности транзакций. Возможно, в этом случае вам придется увеличить число серверов баз данных и установить дополнительное связующее ПО в виде монитора транзакций, чтобы информационная система справилась с нагрузкой.

Серверы баз данных различных поставщиков имеют собственный синтаксис хранимых процедур. Так, в сервере Oracle реализован язык PL/SQL, а в MS SQL Server — язык Transact-SQL. Это несколько ограничивает возможность применения хранимых процедур, ведь вам вряд ли захочется выбрасывать массу наработанного кода, если вы вдруг поменяете поставщика СУБД. Тем не менее мы считаем, что разумное использование хранимых процедур способно в равной степени повысить производительность приложений и в клиент-серверной среде и в среде Web.

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

Трафик Web-приложений имеет несколько иную структуру, поскольку сеть задействуется каждый раз при обращении пользователя к HTML-странице или к соответствующему фрагменту приложения на JavaScript или Java, хранящемуся на Web-сервере. Кроме того, повышенная сетевая активность наблюдалась при передаче данных с Web-клиента на Web-сервер, а также при обращении сервера приложений к СУБД. (В нашей конфигурации модули бизнес-логики и ПО Web-сервера работали на одном и том же компьютере.)

Интересно, что трафик в гораздо большей степени зависел от используемого сервера баз данных (Oracle, MS SQL Server или DB2), чем от архитектурного подхода. В частности, для Oracle мы наблюдали наименьший сетевой трафик, а для SQL Server — наибольший.

Большое значение имеют и используемые сетевые протоколы. Так, наиболее «разговорчивым» оказался протокол NetBEUI, IPX/SPX был более умеренным, и самым «лаконичным» был TCP/IP. Мы также смогли снизить трафик службы DNS (Domain Name Service), используя непосредственные адреса серверов баз данных вместо их доменных имен. Но для сетевых администраторов применение этого метода означает дополнительную работу при установке новых машин.

Загрузка администратора

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

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

В Web-среде у администратора примерно те же задачи. Однако на поддержку пользователей, связанную, например, с перезапуском «зависших» приложений, у него уходит гораздо меньше времени, поскольку Web-браузеры, такие, как Microsoft Internet Explorer или Netscape Navigator, «зависают» гораздо реже программ, выполненных с помощью средств разработки наподобие Visual Basic или Delphi . Кроме того, браузер автоматически получает классы мини-приложений Java с Web-сервера, поэтому администраторам не приходится заботиться о распространении пользовательских приложений на локальные диски.

Задача выравнивания нагрузки также обычно ложится на плечи сетевых администраторов. Она подразумевает добавление файл-серверов, Web-серверов, серверов баз данных и приложений по мере увеличения числа пользователей и последующую настройку приложений, с тем чтобы они могли распознавать добавленные ресурсы. Но если вы используете такое связующее ПО, как, например, монитор транзакций TUXEDO фирмы BEA Systems, то работы у вас будет намного меньше: этот продукт позволяет автоматически распознавать новые ресурсы, а также регулировать вычислительную мощность при изменении интенсивности транзакций.

Сравнение по надежности

Web-подход в общем оказался более надежным, чем клиент-серверный. Поддержка программы, т. е. необходимость внесения новых полей редактирования или изменение старых, делают ПО клиент-сервер менее стабильным. Эпитет «толстый» стал синонимом определения «сложный». Отладка и тестирование приложений клиент-сервер — довольно сложный процесс, поскольку они содержат большое число тесно взаимодействующих модулей. С другой стороны, когда во время тестирования неожиданно начинали «сыпаться» ошибки, обнаружить их в «толстом» клиенте было значительно легче: ОС Windows выводила на экран соответствующее сообщение.

Характерно, что в Web-среде «зависшая» DLL, написанная с помощью ISAPI, выводила сообщение на консоль сервера приложений, но пользователь при этом продолжал смотреть на неменяющийся экран браузера. В случае серьезной ошибки исполнения модуля DLL операционная система Windows NT будет вынуждена завершить работу Web-сервера IIS (Internet Information Server) вместе с приложением. С точки зрения надежности поставщикам следовало бы разрабатывать более совершенные методы отражения проблем сервера приложений для тех, кто использует Web-браузер.

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

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

Один раз мы случайно внесли в клиент-серверную программу ошибку, которая при введении определенной комбинации символов в поле ввода приводила к серьезному сбою. В приложении, написанном на JavaScript или Java, подобной ошибки избежать гораздо легче благодаря простоте кода на стороне клиента. Хотя, конечно, ни один из подходов не гарантирует полной надежности. Но ясно, что сложность программы влечет за собой ошибки так же неизбежно, как болото — комаров. Клиент-серверный подход требует лучших навыков программирования и большей аккуратности.

Победителем становится.

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

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

Трехуровневая клиент-серверная архитектура

Для решения этих проблем и была предложена так называемая 3-х уровневая архитектура клиент-сервер (рис.1.9). Основным ее отличием от архитектуры 2.5 является физическоеразделение программ, отвечающих за хранение данных (СУБД) от обрабатывающих эти данные программ (сервер приложения (СП). Такое разделение программных компонент позволяет оптимизировать нагрузки как на сетевое, так и на вычислительное оборудование комплекса.

Рисунок 1.9 – Схема трехуровневой архитектуры ИС

Компоненты трехуровневой архитектуры, с точки зрения программного обеспечения реализуют определенные серверы БД, web-серверы и браузеры. Место любого из этих компонентов может занять программное обеспечение любого производителя. Модель сервера приложений показана на рис.1.10.

Ниже представлено описание взаимодействия компонентов трехуровневой архитектуры клиент-серверного приложения. Сервер БД представлен MySQL-сервером; сервер приложений технологиями: ADO.NET, ASP.NET и web-сервером IIS; роль клиента выполняет любой web-браузер.

Схематично работу системы можно представить в виде последовательности: Браузер клиента1-> Сервер IIS2-> Исполняющая среда ASP.NET 2.03-> Провайдер данных ADO.NET 2.04-> Сервер MySQL5-> Провайдер данных ADO.NET 2.06-> Исполняющая среда ASP.NET 2.07-> Сервер IIS8-> Браузер клиента.

Более детально функционирование системы происходит следующим образом.

1 — браузер клиента отправляет HTTP-запрос;

2 — на стороне сервера служба Web Internet Information Server (web-сервер IIS) определяет тип запрашиваемого ресурса, и для случая запроса *.aspx (расширение файлов страниц ASP.NET) загружает соответствующее ему (запросу) расширение Internet Server Aplication Programming Interface (ISAPI). Для страниц aspx это расширение isapi_aspnet.dll. IIS также осуществляет идентификацию и авторизацию пользователя от которого поступил запрос. В свою очередь расширение isapi_aspnet.dll загружает фабрику обработчиков ASP.NET. Далее, фабрика обработчиков создает объектную модель запрашиваемой страницы и обрабатывает действия пользователя.

3 — в ходе генерации ответа приложению ASP.NET может потребоваться обращение к БД, в этом случае используя библиотеки классов провайдера данных ADO.NET 2.0, выполняющая среда обращается к серверу БД;

4 — провайдер данных ADO.NET 2.0 передает запрос на операцию с БД серверу MySQL;

Рис.1.10 – Модель сервера приложений трехуровневой ИС

5 — сервер MySQL осуществляет обработку запроса, выполняя соответствующие операции с БД;

6 — провайдер данных ADO.NET 2.0 передает результаты запроса объекту страницы;

7 — объект страницы с учетом полученных данных осуществляет визуализацию (рендеринг) графического интерфейса страницы и направляет результаты в выходной поток;

8 — сервер IIS отправляет содержимое сгенерированной страницы клиентскому браузеру.

Преимуществом трехуровневой архитектуры является:

1. Меньшая нагрузка на клиентское приложение («Тонкий клиент»).

2. Между клиентской программой и сервером приложения передается лишь минимально необходимый поток данных — аргументы вызываемых функций и возвращаемые от них значения. Это теоретический предел эффективности использования линий связи, даже работа с ANSI-терминалами (не говоря уже об использование протокола http) требует большей нагрузки на сеть.

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

4. Дешевый трафик между сервером приложений и СУБД. Трафик между сервером приложений и СУБД может быть большим, однако это всегда трафик локальной сети, а их пропускная способность достаточно велика и дешева. В крайнем случае, всегда можно запустить сервер приложений и СУБД на одной машине, что автоматически сведет сетевой трафик к нулю.

5. Снижение нагрузки на сервер данных по сравнению с 2.5-слойной схемой, а значит и повышение скорости работы системы в целом.

6. Дешевле наращивать функциональность и обновлять ПО.

К недостаткам архитектуры можно отнести более высокие расходы на администрирование и обслуживание серверной части.

Масштабируемость систем выполненных по трехуровневой архитектуре очень высокая. Одна и та же система может работать как на одном отдельно стоящем компьютере, выполняя на нем программы СУБД, сервера приложений и клиентской части, так и в сети, состоящей из сотен и тысяч машин.

Важным фактором в трехуровневой архитектуре является возможность расширение ее функциональной наполненности. Для расширения функциональности не обязательно менять всюсистему как в случае 2.5-уровневой архитектуры, а достаточно установить новый сервер приложения с требуемой функцией. Отпадают и многие проблемы связанные с переустановкой клиентских частей программы на множестве компьютеров, быть может весьма удаленных, столь актуальные для 2-уровневой схемы — парадигма «тонкого» клиента предоставляет для этого целый ряд возможностей.

Дата добавления: 2020-02-09 ; просмотров: 8612 ; ЗАКАЗАТЬ НАПИСАНИЕ РАБОТЫ

ОСНОВНЫЕ ПОНЯТИЯ АРХИТЕКТУРЫ КЛИЕНТ-СЕРВЕР

1.1. Базовые понятия

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

Термин «клиент-сервер» означает такую архитектуру программного комплекса, в которой его функциональные части взаимодействуют по схеме «запрос-ответ». Если рассмотреть две взаимодействующие части этого комплекса, то одна из них (клиент) выполняет активную функцию, т. е. инициирует запросы, а другая (сервер) пассивно на них отвечает. По мере развития системы роли могут меняться, например некоторый программный блок будет одновременно выполнять функции сервера по отношению к одному блоку и клиента по отношению к другому.

Сервер — один или несколько многопользовательских процессоров с единым полем памяти, который в соответствии с потребностями пользователя обеспечивает им функции вычисления, коммуникации и доступа к базам данных. Сервер можно назвать программу, представляющая какие-то услуги другим программам. Примеры серверов — вебсервер Apache, серверы баз данных — MySQL, ORACLE, сетевые файловые системы и принтера Windows.

Клиент — рабочая станция для одного пользователя, обеспечивающая режим регистрации и др. необходимые на его рабочем месте функции вычисления, коммуникацию, доступ к базам данных и др. Клиентом можно назвать это программа, использующая услугу, представляемую программой сервера. Примеры клиентов — MSIE (MS Internet Explorer), клиент ICQ.

Часто люди клиентом или сервером просто называют компьютер, на котором работает какая-то из этих программ.

В сущности клиент и сервер — это роли, исполняемые программами. Клиенты и сервера физически могут находиться на одном компьютере. Одна и та же программа может быть и клиентом, и сервером одновременно, и т.д… это только роли.

Если проводить аналогию с обществом — банк или магазин — «сервера». Они представляют какие-то услуги своим клиентам. Но банк может в то же время быть клиентом какой-то другой фирмы и т. д…

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

СУБД с персональных ЭВМ ( такие, как Clipper, DBase, FoxPro, Paradox, Clarion имеют сетевые версии, которые просто совместно используют файлы баз данных тех же форматов для ПК, осуществляя при этом сетевые блокировки для разграничения доступа к таблицам и записям. При этом вся работа осуществляется на ПК. Сервер используется просто как общий удаленный диск большой емкости. Такой способ работы приводит к риску потери данных при аппаратных сбоях.

По сравнению с такими системами системы, построенные в архитектуре Клиент — Сервер, имеют следующие преимущества:

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

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

1.2. История…

Архитектура и термин «клиент-сервер» впервые использовались в начале 80-тых годов. Первые приложения с архитектурой «клиент-сервер» были базы данных.

До этого не было ясного разделения — программа обычно всё делала сама — в том числе работала с данными в файловой системе, представлением данных пользователю и др. Со временем рос объем и критичность данных для бизнеса, и это со временем начало породить проблемы (быстродействия, безопасности и другие).

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

По существу «взрыв» популярности технологии «клиент-сервер» был вызван изобретением фирмой IBM простого языка запросов к реляционным базам данных SQL. Сегодня SQL всеобщий стандарт работы с базами данных. В последнее время этот «взрыв» продолжает изобретение Интернета, в котором буквально каждое взаимодействие происходит по архитектуре «клиент-сервер».

1.3. Протоколы

Сервер и клиент в сети между собой «разговаривает» на «языке» (в широком смысле слов), понятном обеим сторонам. Этот «язык» называют протоколом.

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

В нашем же случае, примеры протоколов:

Заметим, что протоколы может быть разных уровней. Классификационные системы уровней может быть разные, но одна из самых известных линеек — OSI (Open Systems Interconnection ), в котором 7 уровней.

Например, HTTP — протокол прикладного (седьмого — самого высокого) уровня, а IP — протокол сетевого (третьего) уровня.

1.4. Распределение функций в архитектуре «клиент-сервер»

В классической архитектуре клиент-сервер приходится распределять три основные части приложения по двум физическим модулям. Обычно ПО хранения данных располагается на сервере (например, сервере базы данных), интерфейс с пользователем — на стороне клиента, а вот обработку данных приходится распределять между клиентской и серверной частями. В этом-то и заключается основной недостаток двухуровневой архитектуры, из которого следуют несколько неприятных особенностей, сильно усложняющих разработку клиент-серверных систем.

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

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

Основные функции серверной СУБД — обеспечение надежности, согласованности и защищенности данных, управление запросами клиентов, быстрая обработка SQL-запросов.

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

Сначала большая часть функций приложения решалась клиентом, сервер занимался только обработкой SQL-запросов. Такая архитектура получила название «толстый клиент — тонкий сервер».

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

Такое решение имеет очевидные преимущества, например его легче поддерживать, т. к. все изменения нужно вносить только в одном месте — на сервере.

рассмотренные выше модели имеют следующие недостатки.

1. «Толстый» клиент:

– усложняется обновление ПО, поскольку его замену нужно производить одновременно по всей системе;


– усложняется распределение полномочий, так как разграничение доступа происходит не по действиям, а по таблицам;

– перегружается сеть вследствие передачи по ней необработанных данных;

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

2. «Толстый» сервер:

– усложняется реализация, так как языки типа PL/SQL не приспособлены для разработки подобного ПО и нет хороших средств отладки;

– производительность программ, написанных на языках типа PL/SQL, значительно ниже, чем созданных на других языках, что имеет важное значение для сложных систем;

– программы, написанные на СУБД-языках, обычно работают недостаточно надежно; ошибка в них может привести к выходу из строя всего сервера баз данных;

– получившиеся таким образом программы полностью непереносимы на другие системы и платформы.

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

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

Тогда возникла тенденция поручить выполнение прикладных задач и бизнес-правил отдельному компоненту приложения (или нескольким компонентам), которые могут работать как на специально выделенном компьютере — сервере приложений, так и на том же компьютере, где работает сервер базы данных. Так возникли трехзвенные и многозвенные архитектуры «клиент-сервер».

Рис. 1. Распределение функций между клиентом и сервером

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

СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ

Глава 11. Проектирование для архитектур клиент/сервер

Архитектура клиент/сервер в последние пять-шесть лет является одной из самых популярных тем. В мире Oracle многие ранние приложения клиент/сервер работали прямо-таки катастрофически плохо — одно внутреннее Oracle-приложение давало ответ на тривиальнейший запрос через три минуты. Оно просуществовало в рабочем состоянии всего около трех часов и было отправлено «на свалку». Многие из тех, кто участвовал в разработке этого приложения, до сих пор работают в корпорации Oracle, но предпочитают об этом не вспоминать — это факт просто стерли из корпоративного знания. Большинство причин, приведших к этой катастрофе, устранены благодаря усовершенствованию аппаратных средств и нововведениям в последних версиях ПО, но некоторые из ключевых причин существуют до сих пор. В этой главе мы не раз будем упоминать это неудачное приложение, чтобы напомнить вам, как важно для проектировщиков учитывать особенности среды клиент/сервер.

Два ключевых момента являются залогом успешного проектирования приложений клиент/сервер:

• учет числа операций обмена (пар сообщений), особенно там, где может использоваться глобальная сеть, — именно это и вызвало неудачу упомянутого выше приложения;

• отделение задачи управления пользовательским интерфейсом (роли клиента) от задачи управления данными (роли сервера) — нарушение этого принципа является основной причиной высокоинтенсивного графика сообщений между клиентом и сервером.

Архитектура клиент/сервер — не волшебное средство от перегрузки серверов, но и пренебрегать ей не следует. При разумном применении она дает проектировщику экономически эффективный способ предоставить пользователю высококачественный оперативный интерфейс.

Когда Microsoft Windows 3.1 стала доминирующей настольной операционной системой, широкое распространение получили привлекательные, удобные в работе персональные приложения, например текстовые процессоры и электронные таблицы. Диапазон средств подготовки документов быстро расширился, в нем появились как средства DTP, так и пакеты создания презентаций. Интерфейсы на базе командной строки, которые продолжали использовать для доступа к приложениям, работающим на корпоративных серверах и серверах подразделений, стали выглядеть менее привлекательно, чем интерфейсы настольных приложений. Кроме того, во многих случаях такие серверы были катастрофически перегружены. Сервер не только нес большую нагрузку, связанную с базой данных, — часто каждое нажатие клавиши на подключенном к нему терминале вызывало прерывание центрального процессора, необходимое для обработки операции ввода-вывода и отображения введенного символа на экране.

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

Переход к архитектуре клиент/сервер все-таки дает одно очень важное преимущество — возможность предоставить графический пользовательский интерфейс (7770), не модернизируя сервер. Стало очевидным, что во многих (даже, может быть, в большинстве) приложениях ГПИ стал считаться обязательным (а не просто желательным) по той простой причине, что пользователи персональных приложений к нему привыкли. Собираясь выполнять серверные приложения на своих ПК, пользователи рассчитывают, что эти приложения будут вести себя, как Windows-приложения, а не как серверные программы.

В большинстве сред архитектура клиент/сервер стала обязательной. Задача проектировщика — реализовать ее так, чтобы она работала, обеспечивала достаточную производительность и была удобной в сопровождении. В этой главе мы рассмотрим вопросы, без решения которых нельзя создать удовлетворительно работающее приложение клиент/сервер. Однако сначала нам нужно уяснить смысл термина «клиент/сервер».

Что такое архитектура клиент/сервер?

Термином «архитектура клиент/сервер» обозначают модель, в которой доступ к базе данных подразделения или к корпоративной базе данных осуществляется с персонального компьютера или рабочей станции. Однако особенных аппаратных средств для архитектуры клиент/сервер не требуется. Это программная архитектура, в которой один набор программных компонентов (клиенты) с помощью сообщений просит другой набор программных компонентов (серверы) выполнить различные действия. Серверы выполняют затребованные действия и возвращают полученные результаты клиентам (также с помощью сообщений). И клиенты, и серверы посылают свои сообщения не по адресам (как можно предположить), а по именам. В частности, клиенты посылают свои запросы именованным сервисам, а не конкретным машинам, рассчитывая при этом, что в результате разрешения имен будет определен необходимый физический сервер.

Поскольку связь между клиентами и серверами осуществляется с помощью сообщений, клиентская программа и сервис могут работать на разных машинах. Кроме того, поскольку клиентская программа «знает» сервис только по имени, она не осведомлена о местоположении сервера, предоставляющего данный сервис. Все это реализуется благодаря целому ряду уровней программного обеспечения. Естественно, где-то в глубине машины что-то должно знать, где на самом деле находится нужный сервис. В среде Oracle SQL*Net версии 2 эта информация обычно находится в файле с именем msnames.ora.

Главной чертой архитектуры клиент/сервер является то, что клиент посылает сообщения именованным сервисам. Это дает ряд важных преимуществ:

1. Клиентский и серверный процессы не обязательно должны находиться на одной и той же машине, хотя это вполне допустимо (по данному определению).

2. Клиентский и серверный процессы не обязательно должны работать на однотипных аппаратных средствах или даже под управлением одинаковых операционных систем, если они могут посылать друг другу сообщения. Более того, клиент и сервер не обязательно должны «знать» об аппаратных и программных средах друг друга. Привязка к этим средам — основной источник проблем в приложениях клиент/сервер, потому что какие-либо изменения на клиенте или сервере могут сделать всю систему неработоспособной.

3. Этот процесс может продолжаться до бесконечности: клиент направляет запрос к именованному сервису, который передает его другому именованному сервису, и так далее, как показано на рис. 11.1. Клиент совсем не знает, что первый сервер задействовал других участников (конечно, если не учитывать, что все сетевые операции занимают время и такой «субподряд» часто увеличивает время реакции до неприемлемого). Одна из задач картриджей, которые включаются в архитектуру сетевых вычислений Oracle (NCA), рассмотренную в главе 12, состоит в том, чтобы упростить проектировщикам и программистам такое распределение функций.

Рис. 11.1. Схема вложенной архитектуры клиент/сервер

Все эти положения описывают инкапсуляцию, которая является одним из ключей к успешному проектированию вообще и необходимым условием хорошей работы любого приложения, построенного на клиент-серверных методах. Обработка сообщений, используемая в архитектуре клиент/сервер, знакома каждому, кто работал с Web-броузерами Netscape Navigator или Microsoft Internet Explorer (это приложения клиент/сервер, применяющие протокол HTTP). Web-броузеры также иллюстрируют ту мощь, которую дает возможность работать с несколькими серверами. В более традиционных приложениях клиент/сервер, особенно в тех, которые пользуются инструментальными средствами и серверами БД Oracle, наблюдается тенденция к соединению каждого клиента с одним и только одним сервером.

Об аппаратных средствах

В системах клиент/сервер конца 80-х, начала и середины 90-х годов обычно использовалась довольно мощная рабочая станция, на которой работало ПО на базе оконного интерфейса и которая взаимодействовала с сервером, реализованным на миникомпьютере среднего класса. Первоначально это были Unix-станции с ПО Motif, а сейчас это чаще всего ПК на элементной базе Intel с операционной системой MS Windows 3.х или MS Windows 95. В настоящее время в качестве клиентской операционной системы все чаще используется Windows NT Workstation. Мы наблюдаем также более активное внедрение Web-технологии, делающей природу клиентского устройства невидимой — не только для сервера, но, при наличии языков вроде Java, и для разработчика кода, предназначенного для работы на этом клиенте.

Во многих ранних реализациях модели клиент/сервер сервером была большая ЭВМ VAX фирмы Digital с операционной системой VMS. Сегодня сервер в большинстве случаев представляет собой Unix-систему (как правило, с ОС SVR4 и процессором SPARC, Alpha, Intel или PowerPC) с высоким MIPS-показателем и большими объемами внешней (дисковой) памяти. Все чаще в этой роли выступает и ОС Windows NT Server. Чем новее сервер, тем вероятнее, что он будет иметь несколько центральных процессоров и поддерживать несколько гигабайтов оперативной памяти. Многие из первых серверов были существенно ограничены как в мощности процессоров, так и в объемах оперативной памяти.

И клиент, и сервер подключаются к локальной сети, которая используется как магистраль для передачи сообщений. В некоторых случаях клиент и сервер находятся в одной ЛВС, но чаще они общаются через интрасеть — ограниченную совокупность связанных сетей. Доминирующей технологией в Oracle-системах клиент/сервер является Ethernet, но встречаются и кольцевые сети с маркерным доступом. Клиент и сервер могут использовать любой из множества коммуникационных протоколов, включая вездесущий TCP/IP. Благодаря программам многопротокольного обмена Oracle, клиент и сервер могут пользоваться разными протоколами, при этом ПО обмена предоставляет услуги по преобразованию. В настоящее время лишь ограниченное число приложений по-настоящему работают по Internet — говоря простым языком, по неограниченной совокупности связанных сетей, пользующихся общими протоколами. По мере перехода к Internet появляются клиентские устройства, подключенные по коммутируемым линиям, часто с очень маленькой полосой пропускания.

Илон Маск рекомендует:  Что такое код flashwindow

Такая сильная зависимость от технологии локальных сетей стала проблемой для многих организаций, которым требуется обеспечить поддержку удаленных пользователей, входящих в систему из дома или с клиентского узла. Часто в этих организациях разрабатывали два комплекта приложений, выполняющих одни и те же базовые задачи. Один набор приложений поддерживал интерактивных пользователей, которые подключались непосредственно к ЛВС. Второй набор мог включать высокоуровневый протокол выгрузки-загрузки, обеспечивающий обмен информацией между клиентом и сервером за относительно короткий сеанс и позволяющий пользователям работать в значительной степени автономно. Все было бы намного проще, если бы удаленных пользователей можно было рассматривать как локальных. Поскольку SQL*Net поддерживает много протоколов, включая WinSock, то существует потенциальная возможность работать, скажем, с Oracle Forms no коммутируемой линии. Проблема в том, что быстродействие линии и задержки при передаче сообщений часто делали это приложение неработоспособным. С появлением более скоростных модемов и технологий (например ISDN) ситуация несколько улучшилась, но, тем не менее, ее всегда следует учитывать при проектировании — приложение должно обеспечивать приемлемую скорость работы по самому медленнодействующему из поддерживаемых им каналов.

Если клиент и сервер находятся в разных сетях, то эти сети нужно каким-то образом связать, для чего часто применяется мост, работающий по глобальной сети. Мосты иногда работают на три порядка медленнее, чем локальные сети, которые они связывают. Однако, как мы увидим, пропускная способность сети обычно не является фактором, ограничивающим производительность систем клиент/сервер. Гораздо большее влияние оказывает время ответа. Именно большое время ответа обрекло на неудачу Oracle-приложение, о котором мы упоминали в начале главы.

Основные задачи проектирования для архитектур клиент/сервер

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

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

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

Решение проблемы, связанной с операциями обмена, состоит в том, чтобы свести число запросов к минимуму или, что более правильно, составить сложные запросы типа: «Сделать А, сделать В, сделать С, а затем передать мне ответ». Использование хранимых процедур PL/SQL в базе данных позволяет упростить реализацию запросов этого вида средствами Oracle. Что же касается Web-броузеров, то, скорее всего, здесь все зависит от способа доставки ответа сервером.

Нам постоянно приходится слышать, как руководители и технические специалисты говорят о быстродействии или пропускной способности сети как о критическом факторе для систем клиент/сервер. Это не всегда так. При использовании SQL*Net большинство сообщений между клиентом и сервером довольно короткие (десятки или сотни байтов, а не тысячи и миллионы). Поэтому скорость, с которой сеть может передать файл объемом 1 Мбайт, практически не имеет значения — может быть, поэтому поставщики сетей так любят указывать ее! Ключевыми статистическими данными являются время ответа и максимальная скорость передачи пакетов сервером. Время ответа в большинстве TCP/IP-сетей можно измерить с помощью команды ping имя_хоста (или ping -s имя_хоста, если ping просто сообщает о том, что данный хост работает). Это время находится в диапазоне от 1 мс (если клиент и сервер находятся в одной локальной сети) до 400 мс (когда используется мост Х.25). Максимальная скорость передачи пакетов обычно колеблется в пределах от 1000 до 2000 пакетов в секунду, что является абсолютным аппаратным пределом для сетевой интерфейсной платы.

Полоса пропускания сети становится критичной только тогда, когда с сервера на клиент приходится посылать объемные сообщения. Поэтому в любой нормальной структуре клиент/сервер должно быть минимизировано число передаваемых изображений. Разработчики Web-страниц отмечают, что большинство посетителей Web-страницы приходят туда в надежде найти данные, а не графику. У большинства пользователей традиционных приложений клиент/сервер такие же мотивы.

Проектирование для архитектур клиент/сервер

Наша цель как проектировщиков приложений клиент/сервер проста и привлекательна — спроектировать систему так, чтобы и клиент, и сервер выполняли задачи, в которых они сильны (и, следовательно, были освобождены от задач, которые им даются трудно). Клиент обычно качественно обеспечивает работу прикладного интерфейса, а сервер хорошо выполняет обработку совместно используемых данных. Очевидное решение состоит в следующем — реализовать на клиенте прикладной интерфейс, а на сервере (серверах) выполнять все операции над совместно используемыми данными. Чтобы число пакетов было минимальным, запросы к совместно используемым данным объединяются, и многие из них выполняются за один проход. Звучит это очень просто, но в действительности все гораздо сложнее.

Модель рабочей нагрузки в архитектуре клиент/сервер

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

Рис. 11.2. Типы вычислений клиент/сервер

Эта модель распределения рабочей нагрузки оказалась полезной, и ее можно распространить на трехуровневые архитектуры, но она не дает возможности увидеть общую ошибку, которая заключается в попытке распределить все функции — представления данных, логики и управления данными — между клиентом и сервером. Чем жестче вы примените инкапсуляцию к своей схеме, тем меньше вероятность того, что маленькие фрагменты логики управления представлением окажутся глубоко запрятанными в коде управления данными (во многих случаях и довольно большие сегменты задачи управления данными оказываются закодированными непосредственно в уровне представления). В противном случае вы получите сложный, очень «чувствительный» к изменениям прикладной код, который часто невозможно сопровождать с какой-либо степенью надежности. К сожалению, такой стиль очень распространен в проектах на базе Oracle. В значительной степени это является наследием SQL*Forms версий 2 и 3, способствующих созданию так называемых ключевых триггеров (для управления представлением или интерфейсами), которые свободно могли содержать SQL-предложения и вызовы процедур базы данных.

Поскольку возможности SQL*Forms версии 2 в плане трансформации данных были ограничены, программисты также сочли необходимым встраивать правила форматирования в код управления данными (на SQL). Эта практика все еще преобладает сегодня в триггерах Oracle Forms, и они содержат, например, такие предложения:

SELECT INITCAP(cust_name)
INTO cust_name
FROM custs
WHERE cust_ >

В этом примере смешаны требование к представлению данных (интересующее только клиент) и операция управления данными (которая должна выполняться на сервере). Если теперь инкапсулировать выборку данных на сервере с помощью следующего вызова процедуры:

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

Кроме того, на рис. 11.2 не отражены n -уровневые архитектуры. В этих архитектурах уровни управления приложениями, содержащие прикладную логику, находятся между клиентом и сервером данных.

Важность «тонких клиентов»

О различиях между интерфейсом и процессом мы поговорим в главе 16 . Наш подход к вычислениям клиент/сервер полностью соответствует изложенной там концепции. В приложении клиент/сервер на базе Oracle нам следует стремиться к чему-то среднему между распределенной логикой и удаленным представлением данных (см. рис. 11.2) и попытаться добиться, чтобы клиент решал только непосредственно относящиеся к пользовательскому интерфейсу задачи, а сервер — все остальные, включая всю обработку запросов и обновлений, а также внедрение правил обработки данных и бизнес-правил.

Ясно, что клиент «сведущ» в управлении представлением данных пользователю, будь то данные в графической форме, электронная таблица или экран на базе форм. Клиент обрабатывает все события, связанные с клавиатурой и мышью, рисует изображение экранной формы и позволяет манипулировать объектами, представленными на экране, и перемещаться по ним, Конечно, вы не захотите, чтобы клиентское ПО запрашивало с сервера массу необработанных данных (например, целые таблицы), а затем отбирало нужные вам данные. Это не только приведет к увеличению графика в сети, но и значительно увеличит нагрузку на сервер. Тем не менее, мы встречали многих проектировщиков с иррациональной верой в то, что данные можно извлекать из базы данных и передавать по сети, не создавая сколько-нибудь значительной нагрузки на сервер.

Сервер БД Oracle оптимизирован для селективной выборки, т.е. для выполнения реляционных операций, таких как фильтрация, проецирование и соединение, над большими объемами данных. Серверное ПО рассчитано на прием запросов, их обработку и возвращение статуса и (или) данных за минимальное время.

Не нужно, чтобы сервер решал такие задачи, как рисование экранных изображений и выполнение программ повышения производительности клиента. Никто, находясь в здравом уме, не порекомендовал бы такой подход. Однако просто удивительно, как много мы встречали организаций, где все клиентское ПО содержат на совместно используемом диске сервера. Почему? Потому что это облегчает распространение ПО и гарантирует, что все клиенты используют одну и ту же версию. Клиентское ПО обычно состоит из ядра, выполняющего базовые функции (оно реализовано в исполняемом файле), и набора подпрограмм в библиотеках связей (в Microsoft Windows они называются динамически загружаемыми библиотеками, или DLL). Если при обращении к подпрограмме DLL не находится в памяти, приходится загружать с сервера довольно большой двоичный файл. Это может происходить регулярно, если на клиенте недостаточно памяти.

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

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

Сетевой компьютер Oracle

Что представляет собой сетевой компьютер? Идея состоит в том, что если вы используете Web-броузер, поддерживающий Java, то устройство-клиент может содержать только программы для загрузки клиента. Остальная часть нужного кода поступает по сети вместе с данными в форме апплетов. Для успешной работы размер апплетов должен соответствовать пропускной способности сети, а устройство-клиент должно энергично кэшировать принимаемые им апплеты, чтобы, когда они потребуются, их не пришлось загружать вновь. При этом возникает вопрос о непротиворечивости кэша, т.е. об обеспечении того, чтобы кэш клиента всегда содержал самую последнюю информацию. Если вы используете Netscape, то это обычно делается путем установки времени, по истечении которого элементы кэша считаются устаревшими, равным одним суткам. Таким образом, клиент будет использовать устаревшую страницу максимум 24 часа.

Высокоуровневый протокол, с которым работает SQL*Net, очень прост. По сути дела, клиент передает SQL-предложения или анонимные блоки PL/SQL на сервер для выполнения, сервер обрабатывает их и посылает данные обратно клиенту. Если предложением является SELECT, то возвращаются строки (в ответ на команду FETCH, посланную клиентом). Для D ML-операторов и блоков PL/SQL возвращаемые данные представляют собой код завершения оператора и выходные параметры, если они есть. Это показано на рис. 11.3.

Рис. 11.3. Высокоуровневый протокол архитектуры клиент/сервер Oracle

В Oracle полная архитектура клиент/сервер реализована начиная с версии 5, и эта архитектура используется даже в случае, если клиент и сервер находятся на одной машине. Как правило, Oracle применяет двухзадачную архитектуру, в которой клиент и сервер представляют собой два отдельных процесса (даже если они расположены на одной машине). На некоторых платформах их можно объединить в один процесс, хотя обычно это не рекомендуется из-за того, что прикладная программа может повредить SGA и, следовательно, саму базу данных. Многие операционные системы, включая MVS разработки IBM и VMS разработки Digital, допускают использование привилегированных библиотек. При их наличии приложение может вызвать библиотечную программу, например сервер БД, которая обладает привилегией просматривать SGA, даже несмотря на то, что вызывающая программа этого права не имеет. Отметим, что при оперативной обработке транзакций однозадачная архитектура Oracle во многих случаях работает приблизительно на 20% быстрее, чем двухзадачная, благодаря существенному сокращению числа переключений контекста в операционной системе.

В Oracle7 разработчики корпорации сделали ряд важных шагов для повышения эффективности своей архитектуры клиент/сервер. Во многих случаях число сетевых пар (сообщений от клиента к серверу и обратно) необходимое для выполнения одного оператора, сокращено с четырех до одной.

Чтобы понять, какое влияние оказывают наши приложения на сетевой трафик, необходимо изучить механизм обработки SQL-предложений в базе данных Oracle.

Рассмотрим следующее предложение SELECT:

SELECT ord.id
, ord.value
INTO :ord_id
, ;ord_val
FROM orders ord
WHERE ord.cust_ > AND ord.value > :threshold;

Процесс обработки этого простого предложения можно разбить на пять этапов: разбор, определение, привязка, выполнение, выборка. Если не используются средства отложенных вызовов Oracle, то для выполнения каждого этапа требуется минимум одна пара сетевых сообщений. Например, для выполнения этапа разбора клиент обычно посылает текст предложения на сервер, а сервер отвечает кодом статуса, сигнализирующим об успехе или неудаче. (Этапы, перечисленные в этом разделе, должны быть хорошо знакомы всем, кто программировал с помощью Oracle Call Interface (OCI), где их приходится программировать явно.)

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

SELECT ord.id,ord.value
FROM orders ord
WHERE ord.cust_ > :2

SQL*Plus, SQL*DBA и Server Manager никаких преобразований не производят.

Ниже следует краткое описание каждого из пяти этапов обработки SQL-предложения.

SQL-предложение посылается на сервер в виде текстовой строки. Сервер изучает строку, разбивает ее на составные части и проверяет. Проверка касается не только синтаксиса ; Oracle проверяет, чтобы все указанные в предложении объекты действительно существовали в базе данных и были доступны для вызывающего пользователя. Очевидно, проверяются имена таблиц, столбцов, представлений и последовательностей. В результате разбора создается дерево разбора — внутреннее представление SQL-предложения, которое хранится на сервере.

Клиент запрашивает свойства всех переменных в списке SELECT (в примере — ORDERS. > и ORDERS.VALUE). Чтобы ответить на запрос, сервер использует дерево разбора, построенное на предыдущем этапе.

Клиент определяет фактические значения всех связанных переменных в предложении (в данном примере — :ord_id) и передает эти значения на сервер.

Клиент просит сервер обработать предложение и создать совокупность результатов. В этой точке никакие данные-результаты клиенту не возвращаются, а передается лишь статус. Если запрос содержит фразу FOR UPDATE, то для завершения этапа выполнения необходимо посетить и заблокировать все соответствующие строки. Однако совокупность результатов все равно размещается на сервере. Если есть связанные переменные, то первое действие сервера — попросить клиента предоставить их текущие значения. В очень старых версиях это делалось по одной переменной за раз, но в версии 5.1 была введена быстрая привязка, при которой все необходимые значения запрашиваются в одной операции. В Oracle7 библиотечные программы на клиенте (зная, что для выполнения оператора необходимы значения связанных переменных) посылают их автоматически с запросом на выполнение.

Клиент просит сервер передать подмножество данных, полученное при выполнении запроса. Объем возвращаемых данных зависит от величины (размерности) массива переменных в списке SELECT. В общем случае выборка данных-результатов повторяется до тех пор, пока не будет выбран необходимый (например, для заполнения буфера или экранной формы) объем данных или пока не будет возвращен признак окончания выборки. Все это контролируется приложением.

Теперь давайте несколько уточним эту модель выполнения SQL-предложения и выясним, как она влияет на проектирование для архитектуру клиент/сервер.

1. Если SQL- предложение выполняется несколько раз, то обычно нет необходимости разбирать или определять его каждый раз, потому что и клиент, и сервер могут запомнить ранее выполненное предложение. Повторная привязка необходима лишь в случае, когда после предыдущего выполнения адреса (а не значения) каких-либо связанных переменных изменились.

2. DML-операторы (INSERT, UPDATE и DELETE) не требуют выборки. Оператор завершается после выполнения.

3. В Oracle есть механизм, известный как Deferred Call Interface (интерфейс отложенных вызовов), который иногда называют UPIALL. Он позволяет объединить этапы разбора, определения и привязки с выполнением, хранить результаты на клиенте и выдавать их только при получении запроса на выполнение. Это может значительно снизить сетевой трафик, а также повысить общую пропускную способность и уменьшить время реакции в системе клиент/сервер благодаря меньшему числу пакетов данных (правда, те, которые используются, большего размера). Этот протокол применяется в более новых инструментальных средствах Oracle, например Oracle Forms версий 4.0 и 4.5. Если для разработки используется Рго*С, следует инсталлировать версию 1.6, 2.0 или выше, иначе эту технологию применять будет невозможно.

4. Блоки PL/SQL похожи на DML-операторы тем, что не требуют выборки. Такой блок просто выполняется. Все ссылки на внешние переменные в блоке PL/SQL трактуются как связанные переменные (даже если они выбираются в пределах блока). Использование блока PL/SQL для группировки SQL-предложений — хороший способ сокращения сетевого графика. В качестве примера возьмем клиентское приложение, которое изменяет сальдо двух бухгалтерских таблиц на 10%:

UPDATE checking_accounts cac
SET cac.balance = cac.balance * 1.1
WHERE cac.cus_ >
UPDATE savings_accounts sac
SET sac.balance = sac.balance * 1.1
WHERE sac.cus_ >

Даже при полном объединении вызовов это потребует двух пар сообщений — по одной для каждого SQL-предложения. Если эти два предложения заключить в операторы BEGIN . END, образующие блок PL/SQL, то в лучшем случае нужна будет всего одна пара сообщений. (Еще лучше инкапсулировать это действие и перенести эти два предложения на сервер как хранимую процедуру. Чтобы выполнить действие, программа запустит анонимный блок, содержащий вызов хранимой процедуры.) Выполнение операции клиент/сервер в одной паре сообщений дает хороший результат во всех случаях. Это всегда должно быть целью, проектировщика, если предполагается, что связь между клиентом и сервером будет осуществляться через глобальную сеть.

Появляется промежуточное звено

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

Что же понимать под промежуточным ПО в контексте нашей главной темы — проектирование баз данных? В архитектуре клиент/сервер мы рассматривали внешнее приложение (клиент), которое инициирует выполнение SQL и PL/SQL в базе данных (на сервере). Промежуточное ПО — это слой программного обеспечения, находящийся между клиентом и сервером. Оно может располагаться на компьютере-сервере, компьютере-клиенте или на отдельной машине. Для повышения пропускной способности в нем может использоваться менеджер транзакций, такой как Tuxedo или CICS-система.

Одно из главных обоснований существования промежуточного ПО — обеспечение независимости внешнего приложения от базы данных. В этом случае клиент может использовать собственный язык высокого уровня или протокол для взаимодействия с промежуточным ПО. Ему будет совершенно безразлично, куда передает информацию это промежуточное ПО — в базу данных Oracle или в базу данных Sybase. Если же такое ПО генерирует SQL, строго соответствующий стандарту ANSI-92, то становится простой замена одной СУБД на другую. Даже если такая совместимость с базами данных других производителей не требуется, промежуточное ПО может оградить клиентское ПО от влияния изменений, вносимых в структуру базы данных на сервере. Другими словами, здесь мы имеем еще один способ инкапсуляции.

Это демонстрирует простой пример на рис. 11.4. Промежуточное ПО принимает высокоуровневый вызов от клиента через интерфейс прикладного программирования (API) и конвертирует его в SQL-предложение. В этом простом примере промежуточному ПО не нужно конвертировать возвращаемые с сервера данные — оно просто передает их клиенту. Промежуточное ПО должно обладать значительным интеллектом или иметь исключительно сложный преобразующий уровень, предназначенный для конвертирования вызовов в SQL.

Рис. 11.4. Использование промежуточного ПО между клиентом и сервером

Одним из относительно дешевых и простых вариантов реализации решения с промежуточным ПО является использование на клиенте только вызовов хранимых процедур и функций и разработка библиотеки или пакета процедур либо функций для обслуживания всех запросов приложения. Иногда это решение реализуют частично и сохраняют в клиентском приложении все предложения SELECT, которые могут возвращать несколько строк. В версии 7.2 появилась возможность передавать курсоры между приложениями, что позволяет достаточно изящным способом послать «многострочные» предложения SELECT для выполнения на сервер и передать результаты обратно. В версии 7.3 и в PL/SQL версии 2.3 поддержка этих функциональных возможностей значительно усовершенствована. Помимо сокращения сетевых затрат, этот подход к проектированию позволяет использовать разделяемые курсоры и уменьшить затраты на синтаксический анализ.

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

Преимущество промежуточного ПО — способность избежать зависимости от базы данных для наших приложений, однако каковы при этом затраты и риски? Конечно, с появлением нового уровня, который может быть потенциальным источником проблем, становится более сложной диагностика. Может пострадать и производительность, поскольку промежуточное ПО должно обслуживать запросы индивидуально и многозадачную работу может не обеспечить. В результате запросы могут попадать в очередь и ждать освобождения промежуточного ПО. Эти риски можно уменьшить с помощью менеджера транзакций, управляющего промежуточным ПО.

Один из побочных эффектов от использования промежуточного ПО, который может вызвать проблемы с производительностью, касается применения подсказок в предложениях SQL. Во-первых, некоторые драйверы ODBC «рационализируют» SQL, вырезая комментарии перед направлением предложений на сервер. Но ведь в комментариях содержатся подсказки для оптимизатора по стоимости в Огас1е7. Во-вторых, драйверы ODBC часто переформатируют SQL, и при этом могут быть исключены другие использованные методы настройки. И кроме того, иногда приложение на клиенте обладает сведениями об объеме или содержимом ожидаемых данных, которые нельзя просто так передать промежуточному ПО или конвертировать с его помощью. Вследствие этого возникает мысль о написании промежуточных программных компонентов для конкретных приложений, а это противоречит концепции промежуточного ПО. Очень разумным подходом является ввод уровня прикладной логики, который изолирует управление интерфейсом на клиенте от управления данными на сервере базы данных.

Однако наличие такого среднего уровня означает, что мы уже перешли от простой архитектуры клиент/сервер к трехуровневой архитектуре. Эта архитектура обладает значительными теоретическими преимуществами, но инструментальные средства Oracle поддерживают ее плохо. Кроме того, она не очень популярна в сообществе пользователей Oracle, несмотря на то, что архитектура сетевых вычислений Oracle должна обеспечивать непосредственную поддержку трехуровневой обработки. (Эта тема также обсуждается в главе 16.)

Приемы проектирования для архитектур клиент/сервер

В этом разделе описываются возможности среды клиент/сервер, о которых необходимо знать при проектировании приложений для этой среды.

Кэширование неизменяемых данных на клиенте

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

Таблица 11.1. Таблица финансовых месяцев

5 апреля 1996 г.
6 мая 1996 г.
5 июня 1996 г.
и т.д.

5 мая 1996 г.
4 июня 1996 г.
7 июля 1996 г.
и т.д.

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

Ясно, что для этой совершенно ненужной пересылки данных мы задействуем ресурсы сети и центрального процессора сервера. Очевидное решение — извлечь эти данные при первом обращении к ним пользовательского интерфейса, а затем хранить их на клиенте для обслуживания последующих запросов. Если объем этих данных невелик, то клиентское ПО может направлять запрос на их получение при запуске приложения на клиенте. Таким образом , программа пользовательского интерфейса всегда может рассчитывать на их наличие. Реализация этого механизма зависит от клиентского ПО. Например, в приложении на Visual C++ можно выделять память динамически и хранить эти данные в связанных списках. В Oracle Forms 4.5 для хранения кэшированных значений можно пользоваться группами записей.

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

Давайте в качестве примера рассмотрим таблицу, содержащую описание деталей. Может оказаться, что из перечисленных в ней 100000 деталей один клиент часто выбирает лишь 100. Если описания деталей в процессе обработки системой клиент/сервер никогда не изменяются (или допускается использование устаревшего описания), то можно реализовать на клиенте механизм движущегося кэша (rolling cache), или исключения давно использовавшихся данных (least recently used).

Этот механизм работает так. Каждый запрос сначала проверяется на предмет того, есть ли данные в кэше. Если данные есть, то они извлекаются из кэша. В противном случае данные передаются с сервера, добавляются в кэш, а затем их получает программа интерфейса. Таким образом, данные вызвавшей программе всегда передаются из кэша, а не прямо с сервера. Каждый элемент данных (в примере — описание детали) выбирается в клиентском сеансе только один раз. К сожалению, если длительность этого сеанса очень велика, то кэш не только может устареть, но и значительно увеличиться в объеме. Однако эти проблемы можно решить, если у вас есть время и энергия на проектирование и создание подходящего решения.

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

Более серьезная задача — обеспечение непротиворечивости данных кэша. Ее можно попытаться решить, применив автоматическое удаление кэшированных элементов по истечении заданного временного промежутка (например, 30 минут) либо при помощи триггера на сервере, который будет заносить дату и время последнего изменения в базовой таблице. Клиентская программа может периодически проверять это производное поле и делать соответствующий кэш недействительным, если данные на сервере с момента начала загрузки кэша изменились. Если клиентская операционная система поддерживает удаленные запросы (RPC), то сервер может автоматически делать кэш недействительным, когда вносится изменение. Однако это решение очень сложное в техническом плане и может вызвать значительные проблемы с производительностью, если число клиентов очень велико или если в кэшированные объекты часто вносятся изменения.

Самая серьезная проблема при любом виде кэша — простом или сложном — заключается в том, что если отсутствует промежуточное ПО, «скрывающее» кэш, то программа пользовательского интерфейса должна знать о существовании кэша и уметь запрашивать из него данные. Таким образом, независимо от того, используется промежуточное ПО или нет, выборка данных, которые могут быть локально кэшированы, не должна осуществляться через SQL, за исключением случая, когда на клиенте работает экземпляр базы данных — однако при этом мы уже имеем дело не только с архитектурой клиент-сервер, а еще и с распределенной базой данных. (Эта тема изложена здесь с точки зрения вычислений клиент/сервер. Более подробно распределение данных рассматривается в главе 12.)

Кэши приложений дают наибольшую выгоду в тех приложениях клиент/сервер, где задействуется глобальная сеть. При этом методе также экономятся ресурсы центрального процессора, даже если и клиент, и сервер работают на одной машине. Однако если ожидается большой объем кэша и сложный алгоритм управления им, то мы рекомендуем рассмотреть альтернативные проектные решения; они могут предполагать наличие распределенной базы данных. Помимо всего прочего, рассматриваемый нами кэш является, по сути, созданной в рамках проекта резидентной базой данных, а Oracle уже затратила массу времени и денег на реализацию серверного кода для сервера базы данных. Сервер Oracle, несмотря на потенциально огромную потребность в памяти и административном внимании, все же работает, тогда как очень сложный администратор кэшей, созданный в рамках проекта, может и не работать.

Кэш на стороне клиента — анализ проблемы

Если вы знакомы с броузером Netscape Navigator, то уже должны были привыкнуть к концепции движущегося кэша на стороне клиента. Вполне вероятно, что вы сталкивались и с проблемой непротиворечивости кэша. Опции Navigator позволяют определить, сохранять ли загруженные страницы локально (на диске) и сколько их можно хранить. Эта возможность исключительно полезна, потому что позволяет избежать задержек, которые наблюдаются при загрузке Web-страниц, содержащих несколько сотен килобайтов растровой графики.

Клиент/сервер и распределенные базы данных

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

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

К тому же, очень немногие ориентированные на базы данных клиентские средства сильны в файловом вводе-выводе. Необходимо подумать и том, как достичь приемлемой производительности при обработке запросов. Допустим, что при необходимости хранить важные данные локально, мы будем хранить их в базе данных (либо Oracle, либо не- Oracle). Кроме того, предположим, что локальная база данных представляет собой версию Oracle, которая либо поддерживает Distributed Database Option, либо способна работать с этой опцией. Это очень важно, поскольку очень немногие разработчики умеют хорошо обращаться с несколькими одновременно открытыми соединениями с базой данных. Кроме того, насколько мы знаем, только немногие широко используемые средства ускоренной разработки приложений (УРП) обеспечивают полную поддержку открытия одновременно нескольких соединений с базой данных. Как правило, множественные соединения поддерживаются только из языков третьего поколения (и, как ни странно, с помощью редко используемой команды COPY из SQL*Plus).

Если у нас есть и локальная, и удаленная базы данных и мы должны работать только с одним соединением, то должны соединяться с локальной базой данных, потому что это — единственный путь, которым мы можем добраться до нее без создания графика сообщений. Ведь мы пытаемся уменьшить трафик сообщений. Таким образом, для каждого пользователя его экземпляр локальной базы данных становится пунктом управления всей его работой. Из этого следует, что любая попытка обеспечить прозрачность расположения может вызвать (и, вероятно, вызовет) появление сетевых соединений (cross-network joins) и распределенных транзакций, требующих использования двухфазной фиксации (описанной в главе 12).

Хотя в каждом последующем выпуске Oracle7 производительность сетевых соединений улучшалась, мы не советуем слепо верить в то, что эти соединения будут оптимизированы, как планировалось. Рекомендуем также точно оценить уровень оптимизации в версии (версиях), которая у вас работает. Если же имеется не-0гас1е-сервер с доступом через шлюзовые продукты, то необходимо еще более тщательное исследование.

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

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

Появление базы данных второго уровня

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

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

Илон Маск рекомендует:  Что такое код imap_listsubscribed

Рис. 11.5. Использование локальных серверов БД для справочных данных в сети

Актуальность справочных данных на промежуточных серверах можно обеспечивать либо с помощью снимков, либо путем симметричной репликации. Этот подход позволяет освободить главный, центральный сервер от значительной доли нагрузки, связанной с обработкой запросов, сократив при этом число операций обмена через глобальную сеть. Если предположить, что в большинстве обновляющих транзакций с клиента обновления будут выполняться только на главном сервере, то расходы на двухфазную фиксацию будут низкими, так как промежуточный сервер попросит главный сервер выполнить однофазную фиксацию. (Снимки и симметричная репликация подробно описаны в главе 12.)


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

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

Сокращение сетевого трафика с помощью представлений

Давайте рассмотрим проблему графика сообщений. Допустим, у нас есть приложение, отображающее сетку (иногда называемую многострочным блоком) заказов. В таблице ORDERS есть столбец CUS_ > который содержит уникальный идентификатор покупателя, разместившего заказ. Нашему приложению нужно отобразить имя покупателя, которое должно быть выбрано из таблицы CUSTOMERS. Предположим, что это приложение предстоит разрабатывать в Oracle Forms 4.0/4.5.

Поскольку Customer Name не является столбцом таблицы ORDERS, нам потребуется написать (или сгенерировать) код для управления этим полем. Нам нужно указать имя покупателя, когда мы отображаем заказ, и, возможно , представить в этом поле список значений, чтобы при создании нового заказа пользователь мог выбрать покупателя из списка.

Вероятно, первое, что приходит вам в голову (особенно если вы такой же старый Forms-хакер, как мы), — это мысль реализовать эти функциональные возможности как триггер POST-QUERY:

POST-QUERY
SELECT cus.name
INTO :ord.cus_name
FROM customers cus
WHERE cus. >

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

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

Добиться того, чтобы выборка всех данных для множества строк вновь осуществлялась за одну операцию обмена с сервером, можно так: необходимо определить представление и построить форму на базе представления, а не на базе таблицы ORDERS. В этом представлении будет выполняться соединение таблиц CUSTOMERS и ORDERS, и оно будет определено следующим образом:

CREATE OR REPLACE VIEW v orders
( id
, cus_id
, cus_name
, date_taken
, pending_reason
.
) AS
SELECT ord.id
, ord.cus_id
, cus.name
, ord.date_taken
, ord.pending_reason
.
FROM orders ord
, customers cus
WHERE ord.cus_ >

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

Во всех версиях Oracle до 7.3 представления, которые содержат соединения, не могут быть объектом DML-операций. Это означает, что операции INSERT, UPDATE и DELETE для них не разрешаются. Версия 7.3 поддерживает обновляемые представления, хотя, как следует ожидать, и здесь существует ряд ограничений. В любом представлении обновляемые столбцы должны принадлежать одной таблице, и эта таблица должна быть защищена по ключу (key preserved). В самом простом случае это означает, что ключ (ключи), по которому выполняется соединение, обновлять нельзя.

Пока вы не станете работать с версией 7.3 (или более новой), вам придется программировать или генерировать триггеры ON-INSERT, ON-UPDATE и ON-DELETE в экранной форме для того, чтобы выполнить обновление через блок, построенный на представлении, содержащем соединение, или фактически на любом необновляемом представлении. Эти триггеры, которые, как правило, создать очень легко, просто явно выдают D ML-операции для базовых таблиц представления. В нашем примере это почти наверняка будет таблица ORDERS, так как совершенно невероятно, что мы будем использовать многострочный блок на базе таблицы ORDERS для корректировки имен покупателей.

Эти явные ON-триггеры будут, конечно, нормально работать даже после перехода на версию 7.3, независимо от того, окажется представление обновляемым или нет. Однако здесь просматривается некая тяжеловесность, потому что форма (или, точнее, блок) теперь зависит от определения представления. Если по какой-то причине вы переопределили представление V_ORDERS для выбора данных из таблицы ORDERS2 и не переписали триггеры в Forms, то эти триггеры попытаются обновить не ту таблицу. В лучшем случае вы отделаетесь ошибкой. Если же вам не повезет, то обновление будет выполнено не в той таблице, что, конечно весьма неприятно.

Операция UPDATE или DELETE, вероятно, выполнена не будет, поскольку она ссылается на целевую строку при помощи идентификатора строки (ссылка по идентификатору строки — стандартный метод для Forms-операций UPDATE и DELETE в строках базовой таблицы), но операция INSERT почти наверняка будет выполнена успешно!

Вопросы оптимизации выполнения запросов более проблематичны. Для большинства сложных многострочных блоков должен выполняться поиск не в одной таблице, а в нескольких. Часто бывает, что внешний ключ допускает неопределенные значения (т.е. эта связь не обязательна), поэтому в таком представлении должно осуществляться внешнее соединение. Первоначальная реакция как разработчика, так и пользователя на блоки, построенные на представлении, почти всегда положительна. Это объясняется тем, что они могут использовать любое из полей как основу для запроса и это устраняет традиционные проблемы, связанные с «запросами к небазовым таблицам». К сожалению, хотя это решение богато функциональными возможностями и создает минимальный трафик сообщений, оно может серьезно увеличить нагрузку на сервер и время ответа.

В качестве примера рассмотрим простое представление, определение которого приведено ниже. Чтобы пример был короче, мы опустили некоторые столбцы, которые читатель рассчитывал увидеть в таблице ORDERS. Однако здесь выполняется соединение по схеме «звезда» и продемонстрировано использование внешних соединений для обработки кодовых полей, значения которых могут быть неопределенными.

CREATE OR REPLACE VIEW v_orders
( id
, settlement_currency
, quotation_currency
, sales_office
, customer_name
) AS
SELECT ord.id
, cc1.name
, cc2.name
, sof.name
, cus.name
FROM orders ord
, currencies cc1
, currencies cc2
, sales_offs sof
, customers cus
WHERE ord.cus_ > AND ord.se_cur = cc1.code
AND ord.qu_cur = cc2.code(+)
AND ord.sof_ >

Соединение по схеме «звезда » называется так потому, что для него очевидна аналогия с соответствующей топологией локальной сети. В следующем примере приводится запрос к представлению V_ORDERS, в котором используется такое соединение.

SELECT id
, customer_name
FROM v_orders
WHERE se_cur = ‘UK Pounds’
AND qu_cur = ‘US Dollars’
AND sof_ ;

У нас есть условия для выбора данных из трех таблиц; каждая из этих таблиц соединяется с таблицей ORDERS, но связей с другими таблицами не имеет. Таким образом, таблица ORDERS находится в центре «звезды». Лучше всего при выполнении этой операции использовать следующую стратегию:

1. Произвести запросы к таблицам валют (дважды) и таблице отдела сбыта.

2. Получить декартово произведение результатов этих запросов (в этом случае декартово произведение будет состоять всего из одной строки).

3. Используя это декартово произведение, выполнить соединение с таблицей ORDERS.

4. Выполнить соединение таблицы ORDERS с таблицей CUSTOMERS.

Шаги 1, 2 и 3 — это соединение по схеме «звезда», а версии до 7.3 выдают неудачные планы выполнения запросов, использующих такое соединение. К сожалению, не особенно помогают в этом случае даже подсказки. Причин этому две. Во-первых, механизмы выполнения запросов в ранних редакциях располагают нормальной стратегией для реализации подсказки. Во-вторых, в большинстве Forms-приложений трудно предсказать, какие из допустимых аргументов будут указаны (потому что они вводятся как критерии запроса), а от этого зависит план. Например, нельзя использовать ту же последовательность табличных ссылок, если заданы два наименования валют и имя покупателя (а не Sales Office). При отсутствии поддержки для соединений по схеме «звезда» в механизме выполнения запросов самый лучший подход к такому соединению — кодировать его при помощи процедур.

Проблема с внешними соединениями состоит в том, что оптимизатор запросов Oracle никогда не выдаст план запроса, который выполняется «неверно» по внешнему соединению. Это имеет место даже в случае, если имеется условие, показывающее, что для выбираемых данных не нужно создавать внешнее соединение вообще. Следовательно, наличие внешних соединений в этом примере означает, что запросы с соединением по схеме «звезда» фактически использовать нельзя. Поэтому порядок соединения будет таким:

1. Произвести запрос к таблице CURRENCIES для получения кода валюты в которой указана стоимость заказа.

2. Используя этот код, выполнить соединение с таблицей ORDERS.

3. Произвести соединение таблицы ORDERS с таблицей CUSTOMERS таблицей CURRENCIES и таблицей SALES_OFFS, применяя после этих соединений фильтры для второй и третьей таблиц.

Если лишь очень немногие заказы регистрируются в долларах США, а оплачиваются в английских фунтах (а это весьма вероятно), то этот план выполнения запросов будет крайне неэффективным. Решение, как всегда, заключается в осуществлении процедурного контроля за соединением. Это можно сделать на клиенте или на сервере.

Если реализовать процедурное решение на клиенте, то этим мы увеличим трафик сообщений — а ведь главным мотивом построения блока на представлении было снижение числа сообщений в сети. Если построить блок на представлении, но при этом предотвратить использование этого представления, добавив триггеры ON-SELECT, ON-FETCH и ON-LOCK, вызывающие процедуры PL/SQL на стороне сервера, то таким образом мы полностью инкапсулируем логику запросов на сервере. При этом число пар сообщений будет таким: одна — для инициирования обработки и одна — на каждую строку. Этот метод подходит для блока, содержащего одну строку. Если же речь идет о многострочном блоке, то, чем больше строк нужно в нем заполнить, тем менее приемлемым он становится. Однако этот метод все равно обеспечивает значительное сокращение числа сообщений по сравнению с другим вариантом, который заключается в поиске с помощью нескольких триггеров уровня поля. Кроме того, он позволяет справиться со сложностью запросов к небазовым таблицам силами логики на стороне сервера, а не на стороне клиента.

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

CREATE OR REPLACE PACKAGE order_query IS

PROCEDURE params
( ord_id IN NUMBER
, settlement_currency IN VARCHAR2
, quotation_currency IN VARCHAR2
, sales_office IN VARCHAR2
, customer_name IN VARCHAR2
);

FUNCTION fetch_row
( row_id OUT VARCHAR2
, ord_id OUT NUMBER
, settlement_currency OUT VARCHAR2
, quotation_currency OUT VARCHAR2
, sales_office OUT VARCHAR2
, customer_name OUT VARCHAR2
)RETURN BOOLEAN;
FUNCTION lock_row
( row_id IN VARCHAR2
)RETURN BOOLEAN;

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

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

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

Проверка данных в среде клиент/сервер

В дни Огас1е6 у разработчиков вошло в привычку реализовывать все бизнес-правила и ограничения в приложениях, потому что больше девать их было некуда. В большинстве случаев один и тот же код приходилось повторять в нескольких приложениях, в результате чего возникали проблемы с сопровождением и согласованностью.

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

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

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

Недостаток немедленной проверки данных заключается в том, что правильные данные (а мы надеемся, что их подавляющее большинство) могут проверяться дважды. Вторая проверка выполняется, когда строка зафиксирована и срабатывает триггер проверки на таблице. Как мы уже подчеркивали ранее, мы не хотим снимать этот триггер, так как он — главный страж целостности нашей базы данных. В частности, он защищает базу данных от пользователей, имеющих доступ к средствам создания нерегламентированных запросов. Это показано на рис. 11.6, где лимит кредита не может превысить указанную сумму.

Функция check_credit вызывается дважды — сначала явно из экранной формы для обеспечения немедленной обратной связи в, процессе ввода данных, а затем неявно триггером, когда в таблице выполняется вставка или обновление.

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

Рис. 11.6. Пример дублирования проверки на клиенте и сервере

Важно, чтобы у вас был набор стандартов на разработку ГПИ, четко определяющих подход к проверке в масштабах всего приложения. Экранные формы, которые разработаны в Oracle Forms версии 3 или более старой, а затем конвертированы с помощью какого-либо инструмента, все равно склонны вести себя, как программа, написанная в Oracle Forms версии 3, хотя и выглядят, как ГПИ. В них продолжает выполняться обширная проверка навигационных событий. Такие конвертированные экранные формы, как правило, плохо сочетаются с формами, которые «с нуля» разработаны в Oracle Forms версии 4.5, и весьма вероятно, что их придется переписывать; Привлекательно выглядит еще одна идея (особенно для отделов маркетинга фирм-поставщиков приложений): иметь один и тот же исходный код как для текстовых, так и для ГПИ-версий одного приложения. Но мы считаем эту идею несбыточной — из-за компромиссов, которые она предполагает.

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

Время — это еще одна проблема в приложениях клиент/сервер. От большинства проектировщиков требуют (по крайней мере, они так думают) чтобы на клиенте можно было работать с текущими датой и временем. Во всех средах, за исключением распределенных вычислительных сред, у каждого клиента и каждого сервера есть свои системные часы, и эти часы выдают широкий диапазон несогласованных значений времени. Какое из них должно использовать приложение? Неразбериха возникает и потому, что один и тот же момент времени в разных часовых поясах представлен разным значением.

Распределенная вычислительная среда (Distributed Computing Environment, DCE) — это стандарт, который определяет, как может взаимодействовать ячейка связанных сетью машин. Ячейку в данном контексте можно упрощенно представить как группу машин с общим назначением. Одно из требований DCE состоит в том, что ячейка должна содержать минимум три сервера времени и иметь алгоритм, позволяющий запрашивать время способом, который гарантированно дает непротиворечивое значение в пределах всей ячейки.

Oracle поддерживает использование DCE, и эту СУБД можно конфигурировать на получение SYSDATE с помощью сервисов времени DCE. Конечно, использование DCE влечет за собой дополнительные затраты на обеспечение необходимого уровня производительности.

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

UPDATE orders or
SET ord.tot_amount = ord.tot_amount * 1.01
, ord.latest_update_dt = SYSDATE
WHERE ord.cus_ >

Однако предположим, что от приложения требуется, чтобы пользователь видел метку времени на записи перед тем, как решать, фиксировать запись или нет. Теперь появляется выбор — приложение может запросить дату и время с сервера или воспользоваться локальными часами клиента. Причем результат в данном случае будет зависеть от того, какое средство применялось при его создании. Многие пользователи удивляются, обнаружив, что, когда локальная процедура на PL/SQL, работающая в приложении, созданном в Oracle Forms, обращается к SYSDATE, это приводит к вызову сервера для выборки текущего значения. Единственный путь обратиться к локальным часам — по умолчанию использовать для элементов Forms $$DATE$$ или $$EDATETIME$$.

Не смешивайте эти два метода, т.е. не применяйте $$DATETIME$$ как значение даты и времени по умолчанию с последующим обращением к SYSDATE для выполнения его проверки. У этих значений мало общего — разве что формат.

Во многих клиентских инструментальных средствах предусмотрен вызов, позволяющий получить текущее время из часов клиента (например, в Visual Basic есть функция Now).

Принимая решение о том, откуда брать время, обязательно учтите, что делает приложение и для чего нужно время. Рекомендуем во всех случаях, когда время необходимо передавать в базу данных, использовать серверное время. Если база данных является распределенной, следует брать время с самого центрального сервера. Общее правило (имеющее к архитектуре клиент/сервер отдаленное отношение) звучит так: любая процедура, в которой используется время, должна получать его один и только один раз, чтобы передавать одно и то же время. Вряд ли вы обрадуетесь, когда, закодировав соединение по метке времени, увидите, что данное конкретное время отличается на две-три секунды из-за того, что SYSDATE использовалось в одной долгой транзакции не один, а несколько раз.

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

НОВОСТИ ФОРУМА
Рыцари теории эфира
01.10.2020 — 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]69vJGqDENq4[/Youtube][/center]
[center]14:36[/center]
Osievskii Global News
29 сент. Отправлено 05:20, 01.10.2020 г.’ target=_top>Просвещение от Вячеслава Осиевского — Карим_Хайдаров.
30.09.2020 — 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Ok]376309070[/Ok][/center]
[center]11:03[/center] Отправлено 12:51, 30.09.2020 г.’ target=_top>Просвещение от Дэйвида Дюка — Карим_Хайдаров.
30.09.2020 — 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]VVQv1EzDTtY[/Youtube][/center]
[center]10:43[/center]

интервью Раввина Борода https://cursorinfo.co.il/all-news/rav.
мой телеграмм https://t.me/peshekhonovandrei
мой твиттер https://twitter.com/Andrey54708595
мой инстаграм https://www.instagram.com/andreipeshekhonow/

[b]Мой комментарий:
Андрей спрашивает: Краснодарская синагога — это что, военный объект?
— Да, военный, потому что имеет разрешение от Росатома на манипуляции с радиоактивными веществами, а также иными веществами, опасными в отношении массового поражения. Именно это было выявлено группой краснодарцев во главе с Мариной Мелиховой.

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

ВВЕДЕНИЕ

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

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

Целью курсовой работы является рассмотрение структурированного языка запросов SQL, при помощи которого разрабатываются базы данных для системы клиент-сервер.

Задачами курсовой работы является рассмотрение:

архитектуры информационной системы, и в частности клиент-сервер;

языков запросов SQL и QBE, и их сравнение;

принципов разработки приложений архитектуры клиент-сервер при помощи SQL.

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

АРХИТЕКТУРА ИНФОРМАЦИОННОЙ СИСТЕМЫ

Эффективность функционирования информационной системы во многом зависит от ее архитектуры. В настоящее время перспективной является архитектура клиент-сервер. В достаточно распространенном варианте она предполагает наличие компьютерной сети и распределенной базы данных, включающей корпоративную базу данных (КБД) и персональные базы данных (ПБД). КБД размещается на компьютере-сервере, ПБД размещаются на компьютерах сотрудников подразделений, являющихся клиентами корпоративной базы данных.

Архитектура файл-сервер

Самой простой архитектурой для реализации является архитектура «файл-сервер» (рисунок 1), но она же обладает и самым большим количеством недостатков, ограничивающих спектр решаемых ею задач. Простейшим случаем является случай, когда данные располагаются физически на том же компьютере, что и само приложение.

Рисунок 1 Структура информационной системы с файл-сервером

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

— трудности при обеспечении непротиворечивости и целостности данных;

— существенная загрузка локальной сети передаваемыми данными;

— в целом, невысокая скорость обработки и представления информации;

— высокие требования к ресурсам компьютеров. При этом возникают следующие ограничения.

— невозможность организации равноправного одновременного доступа; пользователей к одному и тому же участку базы данных;

— количество одновременно работающих с системой пользователей не превышает пяти человек для ЛВС, построенной в соответствии со спецификацией 1 OBaseT (скорость обмена данными до 10Мб/с);

При всем этом система обладает одним очень важным преимуществом — низкой стоимостью.

Архитектура «файл-сервер» предусматривает концентрацию обработки на рабочих станциях. Основным преимуществом этого варианта является простота и относительная дешевизна. Подобное решение приемлемо, пока число пользователей, одновременно работающих с базой данных, не превышает 5-10 человек. При увеличении количества пользователей система может «захлебнуться» из-за перегруженности ЛВС большими потоками необработанной информации.

Сервер, как правило, — самый мощный и самый надежный компьютер. Он обязательно подключается через источник бесперебойного питания, в нем предусматриваются системы двойного или даже тройного дублирования. В особо ответственных случаях можно подключить вместе несколько серверов так, что при выходе из строя одного из них в работу автоматически включится «дублер». Таким образом, при концентрации обработки данных на сервере надежность системы в целом ограничивается только материальными средствами, которые заказчики готовы вложить в техническое оснащение.

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

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

Вся тяжесть вычислительной нагрузки при доступе к базе данных ложится на приложение клиента, что является следствием принципа обработки информации в системах «файл-сервер»: при выдаче запроса на выборку информации из таблицы вся таблица базы данных копируется на клиентское место, и выборка осуществляется на клиентском месте. Локальные СУБД используют так называемый «навигационный подход», ориентированный на работу с отдельными записями.

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

В базе данных на файл-сервере гораздо проще вносить изменения в отдельные таблицы, минуя приложения. Эта возможность облегчается тем обстоятельством, что у локальных СУБД база данных — понятие более логическое, чем физическое, поскольку под базой данных понимается набор отдельных таблиц, сосуществующих в едином каталоге на диске. Все это позволяет говорить о низком уровне безопасности — как с точки зрения хищения и нанесения вреда, так и с точки зрения внесения ошибочных изменений.

Недостаточно развитый аппарат транзакций для локальных СУБД служит потенциальным источником ошибок как с точки зрения одновременного внесения изменений в одну и ту же запись, так и с точки зрения отката результатов серий объединенных по смыслу в единое целое операций над базой, когда некоторые из них завершились неуспешно, а некоторые — нет; это может нарушать ссылочную и смысловую целостность базы данных.

Недостатки настольных СУБД обычно проявляются не сразу, а лишь в процессе длительной эксплуатации, когда объем хранимых данных и число пользователей становятся достаточно велики — это приводит к снижению производительности приложений, использующих такие СУБД.

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

Недостатки архитектуры «файл-сервер» решаются при переводе приложений в архитектуру «клиент-сервер», которая знаменует собой следующий этап в развитии СУБД. Характерной особенностью архитектуры «клиент-сервер» является перенос вычислительной нагрузки на сервер базы данных (SQL-сервер) и максимальная разгрузка приложения клиента от вычислительной работы, а также существенное укрепление безопасности данных — как от злонамеренных, так и просто ошибочных изменений.

БД в этом случае помещается на сетевом сервере, как и в архитектуре «файл-сервер», однако прямого доступа к базе данных (БД) из приложений не происходит. Функция прямого обращения к БД осуществляет специальная управляющая программа — сервер БД (SQL-сервер), поставляемый разработчиком СУБД.

Трехуровневая клиент-серверная архитектура

Для решения этих проблем и была предложена так называемая 3-х уровневая архитектура клиент-сервер (рис.1.9). Основным ее отличием от архитектуры 2.5 является физическоеразделение программ, отвечающих за хранение данных (СУБД) от обрабатывающих эти данные программ (сервер приложения (СП). Такое разделение программных компонент позволяет оптимизировать нагрузки как на сетевое, так и на вычислительное оборудование комплекса.

Рисунок 1.9 – Схема трехуровневой архитектуры ИС

Компоненты трехуровневой архитектуры, с точки зрения программного обеспечения реализуют определенные серверы БД, web-серверы и браузеры. Место любого из этих компонентов может занять программное обеспечение любого производителя. Модель сервера приложений показана на рис.1.10.

Ниже представлено описание взаимодействия компонентов трехуровневой архитектуры клиент-серверного приложения. Сервер БД представлен MySQL-сервером; сервер приложений технологиями: ADO.NET, ASP.NET и web-сервером IIS; роль клиента выполняет любой web-браузер.

Схематично работу системы можно представить в виде последовательности: Браузер клиента1-> Сервер IIS2-> Исполняющая среда ASP.NET 2.03-> Провайдер данных ADO.NET 2.04-> Сервер MySQL5-> Провайдер данных ADO.NET 2.06-> Исполняющая среда ASP.NET 2.07-> Сервер IIS8-> Браузер клиента.

Более детально функционирование системы происходит следующим образом.

1 — браузер клиента отправляет HTTP-запрос;

2 — на стороне сервера служба Web Internet Information Server (web-сервер IIS) определяет тип запрашиваемого ресурса, и для случая запроса *.aspx (расширение файлов страниц ASP.NET) загружает соответствующее ему (запросу) расширение Internet Server Aplication Programming Interface (ISAPI). Для страниц aspx это расширение isapi_aspnet.dll. IIS также осуществляет идентификацию и авторизацию пользователя от которого поступил запрос. В свою очередь расширение isapi_aspnet.dll загружает фабрику обработчиков ASP.NET. Далее, фабрика обработчиков создает объектную модель запрашиваемой страницы и обрабатывает действия пользователя.

3 — в ходе генерации ответа приложению ASP.NET может потребоваться обращение к БД, в этом случае используя библиотеки классов провайдера данных ADO.NET 2.0, выполняющая среда обращается к серверу БД;

4 — провайдер данных ADO.NET 2.0 передает запрос на операцию с БД серверу MySQL;

Рис.1.10 – Модель сервера приложений трехуровневой ИС

5 — сервер MySQL осуществляет обработку запроса, выполняя соответствующие операции с БД;

6 — провайдер данных ADO.NET 2.0 передает результаты запроса объекту страницы;

7 — объект страницы с учетом полученных данных осуществляет визуализацию (рендеринг) графического интерфейса страницы и направляет результаты в выходной поток;

8 — сервер IIS отправляет содержимое сгенерированной страницы клиентскому браузеру.

Преимуществом трехуровневой архитектуры является:

1. Меньшая нагрузка на клиентское приложение («Тонкий клиент»).

2. Между клиентской программой и сервером приложения передается лишь минимально необходимый поток данных — аргументы вызываемых функций и возвращаемые от них значения. Это теоретический предел эффективности использования линий связи, даже работа с ANSI-терминалами (не говоря уже об использование протокола http) требует большей нагрузки на сеть.

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

4. Дешевый трафик между сервером приложений и СУБД. Трафик между сервером приложений и СУБД может быть большим, однако это всегда трафик локальной сети, а их пропускная способность достаточно велика и дешева. В крайнем случае, всегда можно запустить сервер приложений и СУБД на одной машине, что автоматически сведет сетевой трафик к нулю.

5. Снижение нагрузки на сервер данных по сравнению с 2.5-слойной схемой, а значит и повышение скорости работы системы в целом.

6. Дешевле наращивать функциональность и обновлять ПО.

К недостаткам архитектуры можно отнести более высокие расходы на администрирование и обслуживание серверной части.

Масштабируемость систем выполненных по трехуровневой архитектуре очень высокая. Одна и та же система может работать как на одном отдельно стоящем компьютере, выполняя на нем программы СУБД, сервера приложений и клиентской части, так и в сети, состоящей из сотен и тысяч машин.

Важным фактором в трехуровневой архитектуре является возможность расширение ее функциональной наполненности. Для расширения функциональности не обязательно менять всюсистему как в случае 2.5-уровневой архитектуры, а достаточно установить новый сервер приложения с требуемой функцией. Отпадают и многие проблемы связанные с переустановкой клиентских частей программы на множестве компьютеров, быть может весьма удаленных, столь актуальные для 2-уровневой схемы — парадигма «тонкого» клиента предоставляет для этого целый ряд возможностей.

Дата добавления: 2020-02-09 ; просмотров: 8613 ; ЗАКАЗАТЬ НАПИСАНИЕ РАБОТЫ

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL