Обзор технологии Web-сервисов. Исследование и разработка методов построения

  • 29.07.2019

Назовем сервисом (service) ресурс, реализующий бизнес-функцию, обладающий следующими свойствами:

    является повторно используемым;

    определяется одним или несколькими явными технологически-независимыми интерфейсами;

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

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

1.1 Основы Web-сервисов

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

В основе Web-сервисов лежат следующие универсальные технологии:

    TCP/IP – универсальный протокол, понимаемый всеми сетевыми устройствами, от мэйнфреймов до мобильных телефонов и PDA;

    HTML – универсальный язык разметки, применяемый для отображения информации устройствами пользователей;

    XML (Extensible Markup Language)– универсальный язык для работы с любыми типами данных.

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

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

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

XML (англ. e X tensible M arkup L anguage - расширяемыйязык разметки ; произносится [икc-эм-эль ]). РекомендованКонсорциумом Всемирной паутины (W3C). Спецификация XML описывает XML-документы и частично описывает поведение XML-процессоров (программ, читающих XML-документы и обеспечивающих доступ к их содержимому). XML разрабатывался как язык с простым формальнымсинтаксисом , удобный длясоздания и обработки документов программам и одновременно удобный для чтения и создания документов человеком, с подчёркиванием нацеленности на использование в Интернете. Язык называется расширяемым, поскольку он не фиксирует разметку, используемую в документах: разработчик волен создать разметку в соответствии с потребностями к конкретной области, будучи ограниченным лишь синтаксическими правилами языка. Сочетание простого формального синтаксиса, удобства для человека, расширяемости, а также базирование на кодировкахЮникод для представления содержания документов привело к широкому использованию как собственно XML, так и множества производных специализированных языков на базе XML в самых разнообразных программных средствах.

Стандартные XML-приложения

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

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

Веб-сервисы пригодны для В2В-интеграции (business-to-business), замыкая приложения, выполняемые различными организациями, в один производственный процесс. Веб-сервисы также могут решать более широкую проблему интеграции приложений предприятия (Enterprise Application Integration, EAI) , осуществляя связь нескольких приложений одного предприятия с несколькими другими приложениями. Во всех перечисленных случаях технологии веб-сервисов являются "связующим звеном", объединяющим различные части программного обеспечения.

Как видно из рис. 1, веб-сервисы представляют собой оболочку, обеспечивающую стандартный способ взаимодействия с прикладными программными средами, такими как системы управления базами данных (СУБД), .NET, J2EE (Java2 Platform, Enterprise Edition), CORBA (Common Object Request Broker Architecture), посредники пакетов планирования ресурсов предприятия (Enterprise Resource Planning, ERP), брокеров интеграции и пр.

Рис.1. Веб-сервисы взаимодействуют с прикладными системами

Интерфейсы веб-сервисов получают из сетевой среды стандартные XML-сообщения , преобразуют XML-данные в формат, "понимаемый" конкретной прикладной программной системой, и отправляют ответное сообщение (последнее - не обязательно). Программная реализация веб-сервисов (базовое программное обеспечение, нижний уровень) может быть создана на любом языке программирования с использованием любой операционной системы и любого связующего программного обеспечения (middleware ).

Простой пример: поиск информации

В настоящее время большинство сервисов вызываются по Сети посредством ввода данных в HTML-формы и отправки этих данных сервису путем добавления их в строку унифицированного указателя информационного ресурса (Uniform Resource Locator, URL ):

http://www.google.com/search?q=Skate+boots&btnG=Google+Search

Этот пример иллюстрирует простоту веб-взаимодействия (например, поиска, покупки акций или запроса маршрута движения), где параметры и ключевые слова внедряются непосредственно в URL. В данном случае представлен простой запрос поиска skate boots (ботинки с коньками) в строке обращения к поисковой машине Google. Ключевое слово search (искать) представляет сервис, к которому будет осуществлено обращение, а параметр Skate+boots является строкой поиска, которая была введена в HTML-форме на странице веб-сайта Google. Сервис поиска Google передаст этот запрос к различным поисковым машинам, которые вернут список URL для страниц, на которых имеется соответствие параметру поиска Skate+boots. Данный малоэффективный способ поиска в Сети полностью основан на установлении соответствия указанной текстовой строки и индексированных HTML-страниц.

XML - лучший способ отправки данных. XML предоставляет значительные преимущества при передаче данных через Интернет. Теперь предыдущий запрос можно представить в виде XML-документа :

xmlns:s="www.xmlbus.com/SearchService">

Skate

boots

size 7.5

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

Данный пример представлен в форме SOAP-сообщения (Simple Object Access Protocol) - стандартной формы обмена XML-сообщениями - одной из технологий, лежащих в основе веб-сервисов. В SOAP-сообщении имя запрашиваемого сервиса и входные параметры представлены в виде отдельных XML-элементов. Рассматриваемый пример также иллюстрирует использование пространства имен XML (xmlns:), еще одного важного элемента веб-сервисов. Благодаря тому, что XML-документы поддерживают разные типы данных, сложные структуры и объединение схем, современные технологии веб-сервисов обеспечивают значительное преимущество над существующими возможностями обращения к программным приложениям посредством HTML и URL.

В данной статье мне хотелось бы обсудить вопросы, связанные с проектированием web сервисов, предназначенных для межпрограммного взаимодействия. Так называемых – интеграционных web сервисов. Прежде всего, это сервисы, которым предстоит работать в различных решениях класса Enterprise Applications Integration (EAI), а также в B2B решениях. Вопросам разработки web сервисов с использованием различных платформ посвящено множество книг и статей, а вот вопросы проектирования освещены гораздо хуже. Вы можете найти массу статей с заклинаниями на тему SOA, которые будут совершенно бесполезны, когда вы приступите к проектированию своего web сервиса.
Итак, давайте рассмотрим ситуацию, когда у вас на руках есть две работающие системы (либо проекты двух систем), и перед вами стоит задача организовать взаимодействие между ними. Вам надоели схемы синхронизации на основе файлов импорта / экспорта, и вы остановили свой выбор на модной, современной и удобной технологии web сервисов. Я попытаюсь рассказать о том, на что следует обратить внимание и как избежать типичных ошибок при проектировании web сервиса для взаимодействия двух систем.

Немного SOA

И все же, сначала пару слов о небезызвестной SOA. Термин Service Oriented Architecture (SOA) довольно серьезно пострадал от беспорядочного употребления в маркетинговых целях. Его так часто употребляют в различных контекстах, что теперь сказать что-то определенное о SOA, кроме того, что это - «сервис ориентированная архитектура», уже трудно.
Тем не менее, SOA имеет такое же право на жизнь, как и «клиент – серверная архитектура» или «много уровневая архитектура». Как и любая другая «архитектура», SOA вводит ряд абстракций и правил, которые помогают нам в разработке определенного класса приложений. В данном конкретном случае, руководствоваться принципами SOA полезно при разработке механизмов взаимодействия и интеграции приложений в масштабе предприятия (Enterprise Applications Integration - EAI).
Итак, начнем с того, что SOA рассматривает приложения как сервисы или совокупности сервисов, которые обмениваются сообщениями напрямую, либо посредством некоторых интеграционных механизмов. Эти сервисы должны удовлетворять ряду условий или требований.
Во-первых, сервис должен иметь определенное «business value», иными словами, сервис должен иметь прикладное значение. Если вы не можете простыми словами объяснить заказчику или пользователю системы для чего нужен ваш сервис, то с точки зрения SOA это неудачный сервис. Пример плохого сервиса: «Сервис для получения глобально – уникальных идентификаторов». Пример хороших сервисов: «Сервис данных о сотрудниках предприятия» или «Сервис приема и обработки счетов к оплате» (Accounts Payable).
Во-вторых, с точки зрения SOA, сервисы должны быть автономными и независимыми. Это необходимо для того, чтобы как это принято в SOA, мы могли комбинировать одни сервисы с другими в зависимости от потребностей бизнеса. Если мы захотели использовать «Сервис приема и обработки счетов к оплате» и при этом узнаем, что нам придется установить и использовать «Сервис бюджетирования и финансового планирования», «Сервис ведения главной книги», и еще дюжину сервисов, то с точки зрения SOA все это выглядит просто отвратительно.
В-третьих, сервис должен быть функционально полным с прикладной точки зрения. Это требование комплиментарно предыдущему. Например, «Сервис приема и обработки счетов к оплате» позволяет добавить заявку, а отследить ее статус не позволяет. Но в принципе мы можем получить отчет по заявкам, из которого можно узнать о статусе заявки. Не правда ли, знакомая ситуация? С точки зрения SOA, да и с любой точки зрения – это не правильно. Сервис должен обеспечивать выполнение всех основных бизнес операций, связанных с прикладной областью или бизнес процессом, который он обеспечивает.
В-четвертых, все сервисы должны уметь предоставлять свои описания в некотором стандартизированном формате. WSDL и UDDI - это варианты форматов описания сервисов.
В-пятых, сервисы должны быть ориентированы на распределенное асинхронное взаимодействие без хранения состояния. Это типично для большинства современных распределенных систем, и это очень важное требование. Достаточно вспомнить, что клиент-серверная архитектура ориентирована на синхронное взаимодействие с хранением состояния, и именно это обстоятельство стало ключевым ограничением для дальнейшего развития этой архитектуры.
В-шестых, SOA предполагает, что благодаря выполнению предыдущих требований, сервисы будут способны объединяться для взаимодействия друг с другом при помощи различных интеграционных инструментов, типа брокеров и маршрутизаторов сообщений, серверов workflow и т.д. и т.п. Ключевым моментом здесь является тот факт, что интеграционные сценарии будут основываться на конфигурировании, часто визуальном, а не на разработке специального «интегрирующего» кода, как это делается в большинстве случаев сейчас.
Вот примерно так выглядят основные вехи, на которые мы должны ориентироваться и которые должны ограничивать нашу разыгравшуюся дизайнерскую мысль в процессе проектирования и разработки интеграционных web сервисов.

Проектирование контракта сервиса.

После того, как Microsoft в своей платформе Windows Communication Foundation – WCF (бывшая Indigo) использовала термин «контракт сервиса», он имеет все шансы сделаться стандартным термином де-факто.
Контракт сервиса - это описание сигнатур всех его операций (методов), плюс описание форматов данных, которыми он оперирует в качестве входных и выходных сообщений.
Для web сервисов контракт исчерпывающе описывается WSDL схемой сервиса. Однако согласитесь, что WSDL не очень хорошо приспособлен для человеческого восприятия. Гораздо нагляднее контракт можно изобразить в виде UML диаграммы классов. К счастью, большинство современных платформ для разработки web сервисов обеспечивают функцию автоматической генерации WSDL описания сервисов.
Правильно спроектированный контракт сервиса, залог успеха, и гарантия того, что ваш сервис проживет долгую и счастливую жизнь, и умрет своей смертью, потому что на смену ему придет новая технология, о которой мы сейчас ничего не знаем.
Microsoft предлагает специальный термин – “contract first” для описания подхода к проектированию, ориентированного в первую очередь, на контракт. Он предполагает, что проектирование сервиса должно начинаться с описания XSD схем сообщений (данных), затем создается WSDL описание операций сервиса, по которому генерируется код класса сервиса. И лишь после этого приступают к имплементации логики. Идея здравая, однако, я повторюсь, что работать с XSD и WSDL не очень удобно, даже с использованием визуальных средств типа XmlSpy. Кроме того, сам по себе принцип “contact first” не гарантирует нам получения правильного контракта сервиса.
Для меня принцип “contact first” означает, что при проектировании сервиса мы должны в первую очередь думать о его контракте и в последнюю - о деталях реализации. Следует взглянуть на будущий сервис c внешней стороны, глазами потребителя данных этого сервиса. Такой взгляд упрощает транспонирование требований предъявляемых к сервису в набор предоставляемых им операций. Например, мы разрабатываем сервис, предоставляющий данные о сотрудниках предприятия. Логично предусмотреть в нем операцию, возвращающую список всех сотрудников. Однако, в ходе анализа требований может оказаться, что потребителю данных нашего сервиса будет интересен, в первую очередь, список сотрудников конкретного подразделения. Это говорит нам о том, что в контракт операции, возвращающей список сотрудников, следует добавить параметр, позволяющий отфильтровать сотрудников конкретного подразделения, либо, нам следует выделить это действие в отдельную операцию сервиса. Такой подход будет соответствовать принципу “contract first”. И напротив, мы могли бы возложить на потребителя данных нашего сервиса обязанность выбрать сотрудников нужного ему отдела из общего списка. Придерживаться подобной стратегии при проектировании интеграционных сервисов – плохая практика. Разбирая конкретный данный случай, мы можем говорить о том, что такое решение не оптимально с точки зрения нагрузки на сервис или объема трафика, а также что такое решение снижает безопасность. Обобщая, можно сказать, что основания простоты и универсальности не должны превалировать при проектировании сервиса. Универсальность сервиса должна достигаться тщательным дизайном. Крайне сложно дать какие либо практические рекомендации в данном направлении. Не легко создать сервис, который бы не состоял из одного метода, вываливающего все внутренние данные системы наружу, и в тоже время был достаточно универсальным для того, чтобы его смог использовать не только тот потребитель, для которого вы проектировали сервис, но и любой другой. Чтобы добиться этого, следует обращать внимание на функциональную полноту контракта сервиса.
Давайте рассмотрим пример. Предположим, существует некая система учета и согласования счетов к оплате, из разряда тех, что обозначаются термином Accounts Payable. Система позволяет вводить данные счетов к оплате, обеспечивает бизнес процесс их согласования и, далее взаимодействует с бухгалтерской системой для формирования платежей. Ввод счетов и их согласование осуществляется, через UI системы. Перед нами стоит задача: создать web сервис, посредством которого другие системы могли создавать счета и отслеживать их статус.
Для простоты, будем считать, что счет к оплате имеет следующую структуру:

Где:
Number – уникальный номер счета, присваиваемый при создании
RecipientID – ссылка на справочник контрагентов, в котором хранятся все реквизиты получателя платежа
Amount – сумма к оплате
PaymentDate – дата оплаты
CategoryID – ссылка на справочник категорий платежей
Owner - имя сотрудника, который создал счет
Description – описание
State – состояния счета, вокруг которого строится бизнес процесс согласования счета.
Итак, исходные требования нам ясны. Схема данных для представления счета, тоже понятна. На основе представленной диаграммы будет создана вот такая XML схема, которая нас вполне устраивает:

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

Выглядит просто ужасно! Давайте разберем, что здесь не так.
Метод добавления счета AddPayment() принимает в качестве параметра структуру Payment, а возвращает номер, присвоенный счету. Структура Payment не очень подходящий тип данных для параметра этого метода, потому что она содержит ряд полей, заполнение которых подчиняется внутренней бизнес логике системы. Это поля Number, State и Owner. Мы не знаем этих бизнес правил, и не знаем, как заполнять эти поля. Для создания счета мы должны указать: получателя, сумму платежа, дату, категорию и описание. Поэтому имеет смысл создать метод именно с такими параметрами, который создаст счет к оплате и вернет его в структуре Payment.
Метод ListPayments() возвращает список счетов в виде массива структур Payment. Возможно, система должна возвращать только те счета, которые были созданы данным пользователем. Однако отсутствие соответствующего параметра в сигнатуре метода не должно вас удивлять. Более надежный и безопасный способ получить данные о пользователе, - взять их из данных аутентификации. Со временем в системе может накопиться огромное количество счетов, и данному методу не помешали бы параметры для фильтрации выдаваемого списка по датам.
Наконец, метод RemovePayment() - принимает номер счета и возвращает true в случае успешного удаления и false в противном случае. Использование Boolean в качестве результата не лучшее решение в данном случае. Причины неудачи операции удаления могут быть самыми различными от простого отсутствия счета с указанным номером, до нарушения логических ограничений системы (например, нельзя удалить счет со статусом Commited). Ситуация довольно распространенная. Ошибка может случиться при выполнении любого метода web сервиса, и, к счастью, инфраструктура web сервисов предлагает стандартный подход к решению этой проблемы. Для передачи данных об ошибке используется SOAP сообщение, в теле которого содержится элемент Fault с информацией об ошибке. Таким образом, нам не нужно расширять контракт нашего web сервиса для передачи сообщений об ошибках, и в случае метода RemovePayment() мы можем вполне обойтись без возвращаемого значения. В случае неудачи удаления счета, информация о причине будет передана в сообщении об ошибке.
После всех изменений наш web сервис будет выглядеть так:

Выглядит значительно лучше, но проблемы остались.
Давайте посмотрим на метод CreatePayment(). Для того чтобы создать счет, нам надо передать пять параметров. С параметрами amount, date, desc, у нас проблем нет. Но вот откуда взять ссылки на получателя (recipient) и категорию (category)? Как я уже упоминал, эти данные представляют собой ссылки на элементы соответствующих справочников нашей системы. И теперь нам становится понятно, что для успешного использования нашего web сервиса, мы должны предоставить доступ к значениям этих справочников.


Таким образом, окончательный вид контракта нашего web сервиса дополнился двумя методами EnumRecipient() и EnumCategory() и двумя типами данных RecipientInfo и CategoryInfo. Их не было в первоначальном контракте и необходимость этих методов не определяется первоначальными требованиями. Они служат для обеспечения синтаксической полноты контракта нашего сервиса. Теперь потребитель данных сервиса может вызвать методы EnumRecipient() и EnumCategory() для получения списков получателей и категорий, выбрать из них необходимые значения, и затем вызвать метод CreatePayment() для создания счета.
Теперь мы можем сказать, что мы спроектировали функционально и синтаксически полный сервис. Также, наш сервис достаточно универсален, и с большой вероятностью его удастся использовать для интеграции с другими системами, перед которыми будут стоять похожие задачи. Кроме того, контракт сервиса и его WSDL описание, включают в себя полные схемы данных всех сообщений. Это очень важно для того, чтобы наш сервис смогли использовать инструменты интеграции типа BizTalk Server, Fiorano ESB, Sonic ESB и др.
На последнем моменте хочется заострить внимание. Формат данных, которыми обменивается сервис, очень важен. Разработчики нередко впадают в одну из двух крайностей. Первая из них, это использование в качестве формата для всех сообщений «голого Xml». Причины тому могут быть самые разные, от попыток использования существующего кода импорта - экспорта Xml данных, до слишком буквального понимания сути web сервисов, как механизма обмена Xml сообщениями. Недостаток такого подхода достаточно очевиден, - схема данных не попадает в WSDL описание контракта сервиса, и это затрудняет его использование. На мой взгляд, существует единственный случай, когда такой подход оправдан. Это случай, когда нам заранее не известен формат передаваемых данных. Во всех остальных случаях, следует использовать типизированные сообщения.
Вторая крайность, это противоположность первой, и выражается она в том, что разработчики пытаются использовать в контракте сервиса существующие в системе внутренние форматы представления данных. Действительно, если в системе уже определены структуры и классы для представления данных (Data Transfer Objects), то почему бы не использовать их в контракте сервиса? Это не всегда это хорошая идея. Внутренние форматы данных могут оказаться не удобными для клиента сервиса. Они могут иметь специфический формат, который не поддерживается клиентской стороной. Пример такого формата DataSet из Microsoft ADO.NET. Данные DataSet прекрасно преобразуются XML и могут быть использованы ASP.NET web сервисами. Однако, это внутренний формат Microsoft, который не является отраслевым стандартом, он имеет свои особенности форматирования Xml представления, которые могут затруднить использование этих данных другими программными платформами web сервисов. Существует масса случаев, в которых использование DataSet оправданно и удобно, но интеграционные сервисы не относятся к их числу.
Таким образом, общие рекомендации по проектированию форматов сообщений web сервисов сводятся к следующему. Всегда старайтесь использовать типизированные сообщения, формат которых описывается определенной Xsd схемой. Проектируйте формат сообщений исходя из функциональных требований, и лишь в том случае, когда полученный формат совпадает с внутренним форматом данных системы, можно подумать об использовании внутреннего формата.

Протокол взаимодействия и его влияние на контракт

Под протоколом взаимодействия web сервиса мы понимаем ту часть требований, которая описывает последовательность взаимодействия сервиса и клиента, направление передачи данных, а также такие аспекты поведения сервиса, как транзакционность, асинхронность, и т.д.
Протокол взаимодействия и контракт сервиса очень тесно связанны. Помимо достаточно простых случаев, когда существует один сервис и его клиент, существуют и более сложные, в которых протокол взаимодействия требует наличия двух и более сервисов. Примером такого протокола может служить протокол асинхронного взаимодействия ASAP
Я не открою большого секрета, если скажу, что отличным способом построить контракт сервиса (по крайней мере, в плане используемых операций) является использование UML диаграмм взаимодействия. Мое личное мнение, наилучшие результаты дает применение Sequence diagram. На рисунке приведена Sequence diagram взаимодействия клиента и сервиса из примера AccountsPayable, рассмотренного выше. К сожалению данный пример достаточно прост, чтобы почувствовать насколько Sequence diagram облегчают проектирование контракта сервиса.

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

Вопросы безопасности

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

  • Аутентификация клиентов сервиса
  • Авторизация клиентов сервиса
  • Безопасность передачи данных
  • Хранение удостоверений для подключения клиентов к сервису
Аутентификация – это процесс подтверждения подлинности пользователя на основе предъявленных им удостоверений. Надежность механизмов аутентификации является критичной для обеспечения безопасности приложения в целом. Поэтому сразу стоит забыть об «анонимном доступе». Наилучший сценарий обеспечения аутентификации, воспользоваться средствами, предоставляемыми платформой web сервисов, которую вы используете. Обычно для аутентификации используются специализированные протоколы (Kerberos, NTLM) и их поддержка встраивается в платформу. Реализация собственных механизмов аутентификации наверняка потребует значительных затрат и чревата потенциальными сложностями реализации и дальнейшей поддержки.
Авторизация - это процесс предоставления пользователю полномочий по доступу к функциям и данным. Естественно, для того чтобы авторизовать пользователя, предварительно он должен быть аутентифицирован. Уловите разницу между аутентификацией и авторизацией. Аутентификация отвечает на вопрос «кто» такой клиент, а авторизация – на вопрос «что» может делать этот клиент. В подавляющем большинстве случаев, бизнес правила по которым тому или иному пользователю предоставляются права доступа к тем или иным данным и операциям определяются в самом приложении. И, следовательно, авторизация – это область ответственности приложения, предоставляющего сервис. Существует множество методов, практик и шаблонов реализации механизмов авторизации, описание которых может быть предметом отдельной статьи.
Помимо аутентификации и авторизации, защита данных при транспортировке их между сервисом и его клиентом является третьей составной частью в обеспечении безопасности web сервиса. Степень защиты определяется характером данных. Различают два способа защиты данных: цифровая подпись и шифрование.
Цифровая подпись используется для подтверждения подлинности данных. Она не защищает данные от несанкционированного прочтения, потому что данные не шифруются. Цифровая подпись позволяет удостовериться в том, что данные принадлежат именно владельцу подписи, а также в том, что данные не были изменены с момента подписи. Механизм цифровой подписи довольно прост. Он основан на использовании не симметричных алгоритмов шифрования, в которых используется пара ключей, один из которых приватный (закрытый) а второй публичный (открытый). Особенность не симметричных алгоритмов состоит в том, что данные, которые зашифрованы одним ключом, можно расшифровать только другим ключом. Цифровая подпись формируется следующим образом. Для данных вычисляется контрольная сумма (хэш код), которая шифруется приватным ключом владельца цифровой подписи. Это и есть цифровая подпись, она добавляется к данным. Так же, к данным может быть добавлен открытый ключ. С помощью открытого ключа, любой пользователь может расшифровать цифровую подпись и получить контрольную сумму, которую можно сравнить с контрольной суммой рассчитанной над текущими данными и, таким образом узнать, изменились ли данные.
В случае, когда нам необходимо не только обеспечить неизменность данных, но и скрыть от посторонних их содержимое, применяется шифрование. Обычно, при передаче данных применяется схема с сеансовым ключом, на механизме которой я не буду останавливаться, поскольку обычно она обеспечивается на инфраструктурном уровне. Итак, цифровая подпись и шифрование являются основными механизмами защиты данных при передаче. Мы можем задействовать эти механизмы на уровне транспортного протокола, либо на уровне сообщений SOAP. Каждый из способов имеет свои преимущества и недостатки.
Для обеспечения защиты данных на уровне транспортного протокола обычно применяют хорошо зарекомендовавший себя механизм SSL. При этом между клиентом и сервером устанавливается защищенное соединение, в котором шифруется весь трафик. Преимущество данного подхода состоит в том, что он практически не требует дополнительных усилий со стороны разработчика (за исключением, может быть некоторых особенностей при установлении соединения). Основная работа по настройке защищенного SSL соединения производится при развертывании приложения. К недостаткам такого подхода можно отнести то, что шифруется весь трафик, а не только те данные, которые действительно являются конфиденциальными, и это требует больших затрат вычислительных ресурсов. Описание того, как использовать SSL совместно с web сервисами ASP.NET 1.1 вы можете найти в моей статье по адресу http://stump-workshop.blogspot.com/2006/10/web-https-ssl.html
Механизмы защиты данных на уровне SOAP сообщений строятся на использовании таких расширений SOAP протокола, как WS-SecureConversation , WS-Trust , WS-SecurityPolicy и WS-Security . Обычно поддержка этих спецификаций встроена на уровне платформы, реализующей web сервисы, и для разработчика они доступны как на декларативном уровне (атрибуты или конфигурирование) так и в виде API. К преимуществам использования данных механизмов относится их гибкость и универсальность. Вы можете использовать как шифрование, так и цифровую подпись. Можно обеспечить защиту только сообщений отдельных операций сервиса, и даже отдельных частей SOAP сообщения. К сожалению не все платформы web сервисов в полной мере поддерживают данные спецификации. Например, в широко распространенном.NET Framework 1.1 нет поддержки WS-Security. Поэтому при использовании данной платформы придется реализовывать защиту на транспортном уровне.
Наконец есть третий путь, - реализовать свой механизм защиты как, например, описано . Следует, однако, понимать, что такой путь резко сокращает возможности использования вашего сервиса.
В заключении, стоит остановиться на таком вопросе, как хранение удостоверений для подключения к web сервисам. Мы уже говорили о том, что доступ к web сервисам следует предоставлять только аутентифицированным пользователям. Обратная сторона медали состоит в том, что нам необходимо указывать удостоверения (credentials) при подключении клиента к сервису. А следовательно, нам необходимо где-то хранить эти удостоверения. Когда нашей системе приходится взаимодействовать с несколькими сервисами, каждый из которых требует свои удостоверения, проблема приобретает особую остроту.
Что такое удостоверения. В большинстве случаев - это пара значений логин – пароль. Иногда это может быть клиентский сертификат или другой тип удостоверений, - все зависит от используемого протокола аутентификации. Следует четко понимать, что клиентские удостоверения относятся к данным, которые могут быть использованы для атаки злоумышленника на систему. Следовательно, эти данные требуют защиты. Вам следует учитывать это обстоятельство еще на стадии проектирования. При реализации интеграционных web сервисов, вам наверняка придется затратить некоторые усилия на разработку механизмов защищенного хранения клиентских удостоверений и их настройки / редактирования.

Вопросы реализации

Вопросы реализации web сервисов сильно зависят от платформы, с которой вы работаете, а их на сегодняшний день существует великое множество. Только Microsoft предлагает 4 платформы (ASP.NET 1.1, ASP.NET 2.0, WSE 1.0-3.0, WCF-Indigo). В мире Java их еще больше. Поэтому давать конкретные рекомендации весьма затруднительно. Однако есть моменты, на которые следует обратить внимание в любом случае.
Большинство платформ берут на себя формирование WSDL описания сервиса, предоставляя разработчику возможность работать с сервисом как с обычным классом. Поэтому, следует уделять постоянное внимание тем деталям, которые оказывают влияние на формирование правильного WSDL описания и XSD схем данных. К этим вещам относится использование Xml Namespace и префиксов, управление порядком сериализации данных, порядком и стилем генерации WSDL.
Следует стараться отделить бизнес логику от реализации сервиса. Хорошо, если у вас получится использовать единую бизнес логику внутри приложения и в web сервисе. В идеальном случае методы вашего web сервиса будут лишены всякой логики, кроме проверки параметров, формирования результатов и обработки ошибок, как показано на рисунке:

Заключение

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

Архитектура распределенных информационных систем и Web-приложений

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

К основным характеристикам распределенных систем:

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

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

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

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

Соответственно, такая распределенная система обычно называется системой промежуточного уровня (middleware). Отметим, что промежуточный уровень распределен среди множества компьютеров.

К особенностям функционирования распределенных систем относятся:

· наличие большого количества объектов;

· задержки выполнения запросов (так если локальные вызовы требуют порядка пары сотен наносекунд, то запросы к объекту в распределенных системах требует от 0.1 до 10 мс);

· некоторые объекты могут не использоваться на протяжении длительного времени;

· распределенные компоненты выполняются параллельно, что приводит к необходимости согласования выполнения;

· запросы в распределенных системах имеют большую вероятность отказов;

· повышенные требования к безопасности.

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

Для борьбы с отказами клиенты обязаны проверять факт выполнения запросов сервером. Безопасность в распределенных приложениях может быть повышена путем контроля сеансов связи (аутентификация, авторизация, шифрование данных).

Архитектура Web-приложений (Web -сервиса) широко применяется в настоящее время. Web-сервис – приложение, доступное через Интернет. Оно предоставляет услуги, форма которых не зависит от поставщика услуг, так как используется универсальная платформа функционирования и универсальный формат данных (XML). В основе Web –сервисов лежат стандарты, определяющие форматы и язык запросов, а также протоколы поиска этих сервисов в Интернете. Схема доступа к базе данных через Интернет показана на рис.1.12.


Рисунок 1.12 – Схема доступа к серверу СУБД через Интернет

В настоящее время существуют три различных технологии, поддерживающие концепцию распределенных объектных систем: EJB, DCOM CORBA.

Основная идея, лежащая в разработке технологии EJB (Enterprise Java Beans ) – создать такую инфраструктуру для компонентов, чтобы они могли бы легко вставляться и удаляться из серверов, тем самым повышая или снижая функциональность сервера. EJB-компоненты являются Java-классами и могут работать на любом EJB-совместимом сервере даже без перекомпиляции. Основными целями EJB-технологии является:

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

2. Описать основные структуры EJB-системы и интерфейсы взаимодействия между ее компонентами.

3. Освободить разработчика от реализации EJB-объектов за счет наличия специального кодогенератора.

Благодаря используемойJava-модели, EJB является относительно простым и быстрым способом создания распределенных систем.

Технология DCOM (Distributed Component Object Model ) - программная архитектура, разработанная компанией Microcoft для распределения приложений между несколькими компьютерами в сети. Программный компонент на одном из компьютеров может использовать DCOM для передачи сообщений к компоненту на другом компьютере. DCOM автоматически устанавливает соединение, передает сообщение и возвращает ответ удаленного компонента. Способность DCOM связывать компоненты позволила Microcoft наделить Windows рядом дополнительных возможностей, в частности, реализовать сервер Microsoft Transaction Server, отвечающий за выполнение транзакций баз данных через Интернет.

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

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

1.1 Принципы построения распределенных веб-систем

Что именно означает создание и управление масштабируемым веб-сайтом или приложением? На примитивном уровне это просто соединение пользователей с удаленными ресурсами через Интернет. А ресурсы или доступ к этим ресурсам, которые рассредоточены на множестве серверов и являются звеном, обеспечивающим масштабируемость веб-сайта.

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

  • Доступность: длительность работоспособного состояния веб-сайта критически важна по отношению к репутации и функциональности многих компаний. Для некоторых более крупных онлайновых розничных магазинов, недоступность даже в течение нескольких минут может привести к тысячам или миллионам долларов потерянного дохода. Таким образом, разработка их постоянно доступных и эластичных к отказу систем и является и фундаментальным деловым и технологическим требованием. Высокая доступность в распределенных системах требует внимательного рассмотрения избыточности для ключевых компонентов, быстрого восстановления после частичных системных отказов и сглаженного сокращения возможностей при возникновении проблем.
  • Производительность: Производительность веб-сайта стала важным показателем для большинства сайтов. Скорость веб-сайта влияет на работу и удовлетворенность пользователей, а также ранжирование поисковыми системами - фактор, который непосредственно влияет на удержание аудитории и доход. В результате, ключом является создание системы, которая оптимизирована для быстрых ответов и низких задержек.
  • Надежность: система должна быть надежной, таким образом, чтобы определенный запрос на получение данных единообразно возвращал определенные данные. В случае изменения данных или обновления, то тот же запрос должен возвращать новые данные. Пользователи должны знать, если что-то записано в систему или храниться в ней, то можно быть уверенным, что оно будет оставаться на своем месте для возможности извлечения данных впоследствии.
  • Масштабируемость: Когда дело доходит до любой крупной распределенной системы, размер оказывается всего лишь одним пунктом из целого списка, который необходимо учитывать. Не менее важным являются усилия, направленные на увеличение пропускной способности для обработки больших объемов нагрузки, которая обычно и именуется масштабируемость системы. Масштабируемость может относиться к различным параметрам системы: количество дополнительного трафика, с которым она может справиться, насколько легко нарастить ёмкость запоминающего устройства, или насколько больше других транзакций может быть обработано.
  • Управляемость: проектирование системы, которая проста в эксплуатации еще один важный фактор. Управляемость системы приравнивается к масштабируемости операций «обслуживание" и «обновления». Для обеспечения управляемости необходимо рассмотреть вопросы простоты диагностики и понимания возникающих проблем, легкости проведения обновлений или модификации, прихотливости системы в эксплуатации. (То есть, работает ли она как положено без отказов или исключений?)
  • Стоимость: Стоимость является важным фактором. Она, очевидно, может включать в себя расходы на аппаратное и программное обеспечение, однако важно также рассматривать другие аспекты, необходимые для развертывания и поддержания системы. Количество времени разработчиков, требуемое для построения системы, объем оперативных усилий, необходимые для запуска системы, и даже достаточный уровень обучения - все должно быть предусмотрено. Стоимость представляет собой общую стоимость владения.

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

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

1.2 Основы

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

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

Пример: Приложение хостинга изображений

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

Вообразите систему, где пользователи имеют возможность загрузить свои изображения на центральный сервер, и при этом изображения могут запрашиваться через ссылку на сайт или API, аналогично Flickr или Picasa. Для упрощения описания давайте предположим, что у этого приложения есть две основные задачи: возможность загружать (записывать) изображения на сервер и запрашивать изображения. Безусловно, эффективная загрузка является важным критерием, однако приоритетом будет быстрая доставка по запросу пользователей (например, изображения могут быть запрошены для отображения на веб-странице или другим приложением). Эта функциональность аналогична той, которую может обеспечить веб-сервер или граничный сервер Сети доставки контента (Content Delivery Network, CDN). Сервер CDN обычно хранит объекты данных во многих расположениях, таким образом, их географическое/физическое размещение оказывается ближе к пользователям, что приводит к росту производительности.

Другие важные аспекты системы:

  • Количество хранимых изображений может быть безгранично, таким образом, масштабируемость хранения необходимо рассматривать именно с этой точки зрения.
  • Должна быть низкая задержка для загрузок/запросов изображения.
  • Если пользователь загружает изображение на сервер, то его данные должны всегда оставаться целостными и доступными.
  • Система должна быть простой в обслуживании (управляемость).
  • Так как хостинг изображений не приносит большой прибыли, система должна быть экономически эффективной.

Другая потенциальная проблема с этим дизайном состоит в том, что у веб-сервера, такого как Apache или lighttpd обычно существует верхний предел количества одновременных соединений, которые он в состоянии обслужить (значение по умолчанию - приблизительно 500, но оно может быть намного выше), и при высоком трафике записи могут быстро израсходовать этот предел. Так как чтения могут быть асинхронными или использовать в своих интересах другую оптимизацию производительности как gzip-сжатие или передача с делением на порции, веб-сервер может переключить чтения подачи быстрее и переключиться между клиентами, обслуживая гораздо больше запросов, чем максимальное число соединений (с Apache и максимальным количеством соединений, установленном в 500, вполне реально обслуживать несколько тысяч запросов чтения в секунду). Записи, с другой стороны, имеют тенденцию поддерживать открытое соединение на протяжении всего времени загрузки. Так передача файла размером 1 МБ на сервер могла занять больше 1 секунды в большинстве домашних сетей, в результате веб-сервер сможет обработать только 500 таких одновременных записей.


Рисунок 1.2: Разделение чтения и записи

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

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

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

К примеру, Flickr решает эту проблему чтения-записи, распределяя пользователи между разными модулями, таким образом, что каждый модуль может обслуживать только ограниченное число определенных пользователей, и когда количество пользователи увеличиваются, больше модулей добавляется к кластеру (см. презентацию масштабирования Flickr,
http://mysqldba.blogspot.com/2008/04/mysql-uc-2007-presentation-file.html). В первом примере проще масштабировать аппаратные средства на основе фактической нагрузки использования (число чтений и записей во всей системе), тогда как масштабировние Flickr просиходит на основе базы пользователей(однако, здесь используется предположение равномерного использования у разных пользователей, таким образом, мощность нужно планировать с запасом). В прошлом недоступность или проблема с одной из служб приводили в нерабочее состояние функциональность целой системы (например, никто не может записать файлы), тогда недоступность одного из модулей Flickr будет влиять только на пользователей, относящихся к нему. В первом примере проще выполнить операции с целым набором данных - например, обновляя службу записи, чтобы включить новые метаданные, или выполняя поиск по всем метаданным изображений - тогда как с архитектурой Flickr каждый модуль должен был быть подвергнут обновлению или поиску (или поисковая служба должна быть создана, чтобы сортировать те метаданные, которые фактически для этого и предназначены).

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

Избыточность

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

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

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

.

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

.

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


Рисунок 1.3: Приложение хостинга изображений с избыточностью

Сегментирование

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

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

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

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

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


Рисунок 1.4: Приложение хостинга изображений с избыточностью и сегментированием

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

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

.

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

1.3. Структурные компоненты быстрого и масштабируемого доступа к данным

Рассмотрев некоторые базовые принципы в разработке распределенных систем, давайте теперь перейдем к более сложному моменту - масштабирование доступа к данным.

Самые простые веб-приложения, например, приложения стека LAMP, схожи с изображением на .


Рисунок 1.5: Простые веб-приложения

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

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


Рисунок 1.6: Упрощенное веб-приложение

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

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


Рисунок 1.7: Доступ к определенным данным

Это особенно трудно, потому что загрузка терабайтов данных в память может быть очень накладной и непосредственно влияет на количество дисковых операций ввода-вывода. Скорость чтения с диска в несколько раз ниже скорости чтения из оперативной памяти - можно сказать, что доступ к памяти с так же быстр, как Чак Норрис, тогда как доступ к диску медленнее очереди в поликлинике. Эта разность в скорости особенно ощутима для больших наборов данных; в сухих цифрах доступ к памяти 6 раз быстрее, чем чтение с диска для последовательных операций чтения, и в 100,000 раз - для чтений в случайном порядке (см. «Патологии Больших Данных», http://queue.acm.org/detail.cfm?id=1563874).). Кроме того, даже с уникальными идентификаторами, решение проблемы нахождения местонахождения небольшой порции данных может быть такой же трудной задачей, как и попытка не глядя вытащить последнюю конфету с шоколадной начинкой из коробки с сотней других конфет.

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

Кэши

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

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


Рисунок 1.8: Размещение кэша на узле уровня запроса

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


Рисунок 1.9: Системы кэшей

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

Глобальный кэш

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

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


Рисунок 1.10: Глобальный кэш, где кэш ответственен за извлечение



Рисунок 1.11: Глобальный кэш, где узлы запроса ответственны за извлечение

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

Распределенный кэш

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

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


Рисунок 1.17: Многоуровневые индексы

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

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

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

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

И это ключевой момент в крупномасштабных системах, потому что даже будучи сжатыми, эти индексы могут быть довольно большими и затратными для хранения. Предположим, что у нас есть много книг со всего мира в этой системе, - 100,000,000 (см. запись блога «Внутри Google Books»)- и что каждая книга состоит только из 10 страниц (в целях упрощения расчетов) с 250 словами на одной странице: это суммарно дает нам 250 миллиардов слов. Если мы принимаем среднее число символов в слове за 5, и каждый символ закодируем 8 битами (или 1 байтом, даже при том, что некоторые символы на самом деле занимают 2 байта), потратив, таким образом, по 5 байтов на слово, то индекс, содержащий каждое слово только один раз, потребует хранилище емкостью более 1 терабайта. Таким образом, вы видите, что индексы, в которых есть еще и другая информация, такая, как наборы слов, местоположение данных и количества употреблений, могут расти в объемах очень быстро.

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

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

Балансировщики нагрузки

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


Рисунок 1.18: Балансировщик нагрузки

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

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


Рисунок 1.19: Множественные балансировщики нагрузки

Как и прокси, некоторые балансировщики нагрузки могут также направлять запросы по-разному, в зависимости от типа запроса. Они также известны как реверсивные (обратные) прокси.

Управление данными, специфичными для определенного сеанса пользователя, является одной из проблем при использовании балансировщиков нагрузок. На сайте электронной коммерции, когда у Вас есть только один клиент, очень просто позволить пользователям помещать вещи в свою корзину и сохранять ее содержимое между визитами (это важно, так как вероятность продажи товара значительно возрастает, если по возвращении пользователя на сайт, продукт все еще находится в его корзине). Однако если пользователь направлен к одному узлу для первого сеанса, и затем к другому узлу во время его следующего посещения, то могут возникать несоответствия, так как новый узел может не иметь данных относительно содержимого корзины этого пользователя. (Разве вы не расстроитесь, если поместите упаковку напитка Mountain Dew в Вашу корзину, и, когда вернетесь, ее там уже не будет?) Одно из решений может состоять в том, чтобы сделать сеансы «липкими», так чтобы пользователь был всегда направлен к тому же узлу. Однако использование в своих интересах некоторых функций надежности, таких как автоматическая отказоустойчивость, будет существенно затруднено. В этом случае корзина пользователя всегда будет иметь содержание, но если их липкий узел станет недоступным, то будет необходим особый подход, и предположение о содержании корзины не будет больше верно (хотя, стоит надеяться, что это предположение не будет встроено в приложение). Конечно, данную проблему можно решить при помощи других стратегий и инструментов, как описанных в этой главе, таких как службы, так и многих других (как кэши браузера, cookie и перезапись URL).

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

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

Очереди

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


Рисунок 1.20: Синхронный запрос

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

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


Рисунок 1.21: Использование очередей для управления запросами

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

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

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

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

  • масштабирование
  • distributed computing
  • web-разработка
  • Kate Matsudaira
  • Добавить метки

    5.1.1 Основы Web-сервисов

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

    В основе Web-сервисов лежат следующие универсальные технологии:

    TCP/IP – универсальный протокол, понимаемый всеми сетевыми устройствами, от мэйнфреймов до мобильных телефонов и PDA;

    HTML – универсальный язык разметки, применяемый для отображения информации устройствами пользователей;

    XML (Extensible Markup Language)– универсальный язык для работы с любыми типами данных.

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

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

    Веб-сервисы могут использоваться во многих приложениях. Независимо от того, откуда запускаются веб-сервисы, с настольных компьютеров клиентов или с переносных, они могут использоваться для обращения к таким интернет-приложениям, как система предварительных заказов или контроля выполнения заказов. Веб-сервисы пригодны для В2В-интеграции (business-to-business), замыкая приложения, выполняемые различными организациями, в один производственный процесс. Веб-сервисы также могут решать более широкую проблему интеграции приложений предприятия (Enterprise Application Integration, EAI), осуществляя связь нескольких приложений одного предприятия с несколькими другими приложениями. Во всех перечисленных случаях технологии веб-сервисов являются "связующим звеном", объединяющим различные части программного обеспечения.

    Как видно из рис. 5.1, веб-сервисы представляют собой оболочку, обеспечивающую стандартный способ взаимодействия с прикладными программными средами, такими как системы управления базами данных (СУБД), .NET, J2EE (Java2 Platform, Enterprise Edition), CORBA (Common Object Request Broker Architecture), посредники пакетов планирования ресурсов предприятия (Enterprise Resource Planning, ERP), брокеров интеграции и пр.

    Рис.5.1. Веб-сервисы взаимодействуют с прикладными системами

    Интерфейсы веб-сервисов получают из сетевой среды стандартные XML-сообщения, преобразуют XML-данные в формат, "понимаемый" конкретной прикладной программной системой, и отправляют ответное сообщение (последнее - не обязательно). Программная реализация веб-сервисов (базовое программное обеспечение, нижний уровень) может быть создана на любом языке программирования с использованием любой операционной системы и любого связующего программного обеспечения (middleware).

    Простой пример: поиск информации

    В настоящее время большинство сервисов вызываются по Сети посредством ввода данных в HTML-формы и отправки этих данных сервису путем добавления их в строку унифицированного указателя информационного ресурса (Uniform Resource Locator, URL):

    http://www.google.com/search?q=Skate+boots&btnG=Google+Search

    Этот пример иллюстрирует простоту веб-взаимодействия (например, поиска, покупки акций или запроса маршрута движения), где параметры и ключевые слова внедряются непосредственно в URL. В данном случае представлен простой запрос поиска skate boots (ботинки с коньками) в строке обращения к поисковой машине Google. Ключевое слово search (искать) представляет сервис, к которому будет осуществлено обращение, а параметр Skate+boots является строкой поиска, которая была введена в HTML-форме на странице веб-сайта Google. Сервис поиска Google передаст этот запрос к различным поисковым машинам, которые вернут список URL для страниц, на которых имеется соответствие параметру поиска Skate+boots. Данный малоэффективный способ поиска в Сети полностью основан на установлении соответствия указанной текстовой строки и индексированных HTML-страниц.

    XML - лучший способ отправки данных. XML предоставляет значительные преимущества при передаче данных через Интернет. Теперь предыдущий запрос можно представить в виде XML-документа:

    xmlns:s="www.xmlbus.com/SearchService">

    Skate

    boots

    size 7.5

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

    Данный пример представлен в форме SOAP-сообщения (Simple Object Access Protocol) - стандартной формы обмена XML-сообщениями - одной из технологий, лежащих в основе веб-сервисов. В SOAP-сообщении имя запрашиваемого сервиса и входные параметры представлены в виде отдельных XML-элементов. Рассматриваемый пример также иллюстрирует использование пространства имен XML (xmlns:), еще одного важного элемента веб-сервисов. Благодаря тому, что XML-документы поддерживают разные типы данных, сложные структуры и объединение схем, современные технологии веб-сервисов обеспечивают значительное преимущество над существующими возможностями обращения к программным приложениям посредством HTML и URL.

    Следующее поколение Сети

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

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

    ОБЩЕЕ ВЗАИМОПОНИМАНИЕ

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

    Преимущества и недостатки веб-сервисов.

    К преимуществам веб-сервисов можно отнести следующее:

      Веб-сервисы позволяют компании интегрировать свои бизнес-процессы с бизнес-процессами бизнес-партнеров и клиентов при меньшей стоимости, чем с использованием других интеграционных технологий. Стоимость подобных решений на основе веб-сервисов доступна даже для SMB (Small and Medium Business), что откроет для таких компаний новые перспективы развития;

      Поскольку веб-сервисы организуются в публичные реестры (UDDI-реестры, ebXML-реестры или иные), доступные заинтересованным лицам по всему миру, порог выхода компаний на новые рынки снижается, возможности же для наращивания клиентской базы напротив возрастают;

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

      Построение новых корпоративных решений с применением веб-сервисов реализуется быстрее и совокупно дешевле, поскольку основное внимание сосредотачивается на создании бизнес-логики решения, программирование самих веб-сервисов лишь по необходимости “обрамляет” этот процесс, не требуя больших трудозатрат за счет эффективного применения повторно используемого кода и адаптированных средств разработки (IDE и SDK).

    К недостаткам (минусам) веб-сервисов можно отнести:

      Стандарты интеграции бизнес-процессов, вопросы управления транзакциями и выработка единых бизнес- и IT-политик взаимодействующих посредством веб-сервисов компаний находятся пока на стадии разработки (мы отметим следующие начинания: Web Services Flow Language (WSFL), Business Process Execution Language 4 Web Services (BPEL4WS (аббревиатура “BPEL” произносится кратко как “бипль”)) корпорации IBM, XLANG корпорации Microsoft и спецификации WS-Coordination и WS-Transaction – результат сотрудничества IBM, Microsoft и BEA). Очевидно, без их четкой формализации и опубликования построение ИС на основе веб-сервисов может идти лишь с переменным успехом;

      Динамическое использование информации бизнес-реестров веб-сервисов, вызов веб-сервисов, требует решения вопросов доверительности отношений между различными бизнес-реестрами. Кроме того, есть трудности в совместном использовании бизнес-реестров различных форматов (например, задача поиска определенного веб-сервиса в UDDI-реестре и ebXML-реестре требует различных подходов в силу различия XML-документов, описывающих один и тот же веб-сервис в каждом из этих реестров. Хотя, надо отметить, что есть попытки решить эту проблему созданием единого браузера реестров. В качестве примера - графическая утилита Registry Browser корпорации Sun Microsystems, реализующая набор интерфейсов JAXR (Java API for XML Registries);

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

      Вопросы безопасности функционирования ИС на основе веб-сервисов пока не урегулированы до конца. Спецификация WS-Security – продукт деятельности корпораций IBM и Microsoft – в настоящее время достаточно молода, не “устоялась” и частично все еще дорабатывается. Однако, в силу общности положений спецификации WS-Security, уже готовится к выпуску следующий слой спецификаций, посвященных вопросам безопасности: Web Services Policy Assertions, Web Services Policy Attachments, Web Services Policy Framework, Web Services Trust, Web Services Secure Conversation, Web Services Federation.

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

    Определение веб-сервиса

    Назовем сервисом (service) ресурс, реализующий бизнес-функцию, обладающий следующими свойствами:

      является повторно используемым;

      определяется одним или несколькими явными технологически-независимыми интерфейсами;

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

    Веб-сервисом (см. документ W3C “Web-services architecture requirements”) называется программная система, идентифицируемая строкой URI, чьи интерфейсы и привязки определены и описаны посредством XML. Описание этой программной системы может быть найдено другими программными системами, которые могут взаимодействовать с ней согласно этому описанию посредством сообщений, основанных на XML, и передаваемых с помощью Интернет-протоколов.