Будущее настало. Cloud Computing доступен массам, а распределенная
архитектура теперь является естественной потребностью не только крупных
организаций, но и самых что ни на есть рядовых граждан. Сегодня мы рассмотрим
систему быстрого развертывания распределенных приложений в домашних условиях.
В рамках этой статьи мы продолжим знакомиться со спектром технологий
платформы .NET Framework. Одна из прошлых статей была посвящена .NET Remoting –
принципу построения сетевых приложений, на основе которого мы организовали
полноценную систему распределенных вычислений. Однако Microsoft не стала
ограничивать фантазию разработчика одним "ремоутингом", который упрощает
разработку сетевых приложений и предоставляет широкий инструментарий для обмена
данными между клиентской и серверной частью, но все же остается ограниченным
рамками архитектуры "клиент-сервер". С ростом функционала проектируемого
приложения растет количество его функциональных элементов, роль которых уже
далека от классического представления.
Целый набор технологий построения безопасных систем с распределенной
архитектурой, в том числе и концепция упомянутой Remoting, вошли в состав
фреймворка Windows Communication Foundation, который, в свою очередь, входит в .NET
Framework. Разработчику предоставляется единая среда создания, поддержки и
развертывания веб-служб, каждая из которых функционирует по принципу "доступна
всем", то есть имеет полностью открытые интерфейсы для функционирования с
другими системами без каких-либо ограничений к своей внутренней архитектуре.
Таким образом, прослеживается связь с технологией, которая имеет модное название
"cloud computing" – служба предоставляется как сервис, а, значит,
предоставляются компьютерные ресурсы и вычислительные мощности. И кто сказал,
что вычисления в облаке – удел крупных компаний?
Однако, инструментарий для программирования систем распределенных транзакций
– не единственная область WCF. Эта технология также обеспечивает поддержку
удобной работы в веб-среде. Модель программирования, которая гордо называется
WCF WEB HTTP, сочетает в себе необходимые для создания многофункциональных
веб-приложений технологии обработки данных: поддержка команд
получения/изменения/вызова данных (GET и POST), обработка унифицированных
локаторов ресурсов (URI), поддержка нескольких различных типов данных (документы
XML, объекты AJAX и JSON, сообщения SOAP). Имеются также средства обеспечения
конфиденциальности, целостности и аутентификации. Теперь проблема разграничения
доступа к административной части твоей бот-сети не ограничивается банальной
передачей пары "логин:пароль" авторизационной форме. Более того, процесс
авторизации может проходить вообще без классической схемы с паролями. Кстати
говоря, грамотно спроектированная политика разграничения доступа (бот, админ,
гость, правоохранительный орган) в системе с распределенной архитектурой – один
из ключевых аспектов, требующих отдельного внимания.
Прежде чем приступить к обзору средств WCF для построения приложений с
распределенной архитектурой, рассмотрим подходы к реализации этих архитектур.
Два сапога…
Для начала ознакомимся с двумя фундаментальными методиками организации любой
распределенки.
В распоряжении архитектора распределенных систем имеются два подхода: SOAP и
REST.
SOAP (Simple Object Access Protocol) – классический подход, в
общем случае представляющий собой обмен сообщениями в распределенной
инфраструктуре. Одной из реализаций данного подхода является уже упомянутая
технология .NET Remoting.
Рассмотрим организацию SOAP на простом примере. Пусть имеется некоторый
"Сервис", предоставляющий методы с описанной в специальном формате структурой. В
нашем случае Сервис предоставляет метод "GetBalance(int AccountID)" получения
баланса на запрашиваемом аккаунте. Клиент генерирует специальный запрос и
отправляет его в составе HTTP-пакета Сервису:
//стандартные HTTP-заголовки
…
SOAPAction: GetBalance
…
//SOAP-конверт
<soap: Envelope xmlns: soap …>
//тело SOAP-запроса
<soap: Body>
<GetBalance xmlns = …>
<Account>2</Account>
</GetBalance>
</soap: Body>
</soap: Envelope>
Формат SOAP-ответа формируется аналогичным образом.
Подход REST (Representational State Transfer) – альтернатива
SOAP. Данный архитектурный стиль построен на таких стандартах, как HTTP, URI,
XML. Акцент в этом подходе сделан не на исполнении удаленных сервисов, как в
SOAP, а на доступе к необходимым ресурсам с помощью их унифицированных
локаторов, называемых URI. Для вызова методов и получения/изменения каких-либо
данных происходит обращение к сервису с помощью стандартных HTTP-глаголов (GET,
POST, PUT, DELETE). Каждый объект кодируется уникальным URL, например:
www.service-site.com/Accounts/2.
Таким образом, данные, полученные по указанному URL, при повторном обращении
к ним могут быть кэшированы.
На первый взгляд, разница несущественна, ведь так или иначе клиент получает
необходимые ему данные, однако, результаты проектирования системы в соответствии
с этими подходами кардинально отличаются. Непосредственное обращение к ресурсам
сервиса с помощью REST-подхода позволяет поднять степень конфиденциальности
клиентской стороны, так как запросы могут фиксироваться исключительно на стороне
веб-службы, чего не скажешь о SOAP-аналоге, где происходит непосредственный
обмен пакетами между клиентской и серверной частью. Еще один аргумент не в
пользу SOAP: обязательный разбор клиентом полученного XML-кода требует
определенных трудозатрат, что плохо сказывается на масштабируемости задачи. REST
в этом плане более практичен и не требует специальных оптимизационных
мероприятий.
Короче говоря, выбор того или иного подхода должен быть основан, прежде
всего, на особенностях решаемой задачи. Например, организация grid-системы,
занимающейся поиском коллизии MD5-хешей, и абсолютно нелегального ботнета,
организующего распределенный поиск заветной "строчки" по известному MD5-хешу –
задачи, требующие индивидуального подхода.
Теперь вернемся непосредственно к WCF и посмотрим, какой набор инструментов
предоставляется разработчику.
Сквозь призму Microsoft
Обмен данными между WCF-клиентом и WCF-сервисом основан на так называемых
"слоях". Клиент, имеющий в своем распоряжении схему обращения к методам сервиса,
генерирует запрос к какому-либо методу. Автоматически создается прокси (а вот и
концепция Remoting’а!) и производится передача ему запроса (списка параметров
для обращения к методу). WCF-прокси кодирует эти параметры, добавляет
необходимые атрибуты безопасности, и, если соответствующие опции заранее были
активированы в конфигурационном файле, отправляет в транспортный канал. Далее,
сервис в обратном порядке извлекает этот запрос, соответствующим образом
обрабатывает (согласно инструкциям метода), и возвращает результат клиенту.
Протоколом передачи данных может выступать один из стандартных протоколов: HTTP,
TCP, MSMQ и др.
WCF "по умолчанию" основан на SOAP. Однако, если использовать только часть
определенных слоев, то можно организовать и REST-подход.
В Windows Communication Foundation есть три ключевых понятия:
- Адрес (Address);
- Связывание (Binding);
- Контракт (Contract).
Эти три атрибута определяют понятие так называемой "оконечной точки" сервиса.
Оконечная точка – "орган" связи сервиса с внешним миром. Ее "Адрес", как ни
странно, определяет адрес нахождения сервиса. Именно для предоставления адресной
информации предоставляемых ресурсов используется URI (унифицированный локатор
ресурсов, проще говоря, их адрес).
Элементы типа "Связывание" определяют, как будет осуществляться
взаимодействие с точкой, то есть какие протоколы будут использоваться на
транспортном уровне (например, TcpTransportBindingElement – передача по
протоколу TCP), будет ли проверяться надежность передачи сообщения (о чем
свидетельствует присутствие элемента ReliableSessionBindingElement) и включена
ли безопасность передачи SOAP-сообщений (наличие элемента SecurityBindingElement).
Каждый из этих элементов, в свою очередь, может иметь ряд атрибутов, уточняющих
их специфику.
Элементы типа "Контакт" представляют собой совокупность операций,
определяющих то, что оконечная точка будет сообщать внешней среде. По сути,
операция – не что иное, как обмен сообщениями (запрос/ответ) или их
односторонняя отправка.
Есть контакт!
Рассмотрим создание оконечной точки WCF-службы для того, чтобы последняя
могла предоставлять потенциальным клиентам свои методы.
Объявление Контакта заключается в создании класса и привязки к нему атрибута
ServiceContractAttribute (и тут Remoting). В свою очередь, метод класса, который
будет передавать обработанные данные во внешний мир, также должен помечаться
атрибутом OperationContractAttribute. Рассмотрим описанные действия на примере
создания метода службы, который принимает два целых числа и отправляет их сумму
обратно во внешнюю среду:
[ServiceContract]
public interface AddIntPoint
{
[OperationContract]
int Add(int x, int y);
}
Как можно догадаться из определения Контакта – в нем должно произойти
сложение двух чисел, а вот его реализация:
public class AddService : AddIntPoint
{
public int Add(int x, int y)
{ return x + y; }
}
Теперь класс AddService является классом WCF-сервиса и может быть вызван
клиентской частью удаленно.
Все гениальное просто. Ты можешь создать абсолютно любой метод, например,
PasswordCrack (string MD5hash) и ждать заветного результата. Что самое
примечательное – ты не будешь замечать, где происходят расчеты (на локальной
машине или где-то на сервере в Зимбабве), так как WCF-прокси сам организует
соединение с удаленной службой и аккуратно передаст тебе результаты выполнения
удаленного метода.
Следующий код демонстрирует определение оконечной точки:
public class WCFServiceApp
{
//метод определения оконечной точки и запуска сервиса
public void DefineEndpointImperatively()
{...}
//эквивалентная оконечная точка в конфигурационном файле
public void DefineEndpointInConfig()
{...}
}
В функции DefineEndpointImperatively() объявляется экземпляр класса, который
реализует нужный функционал, добавляется точка подключения по протоколу HTTP и
происходит запуск службы:
...
ServiceHost sh = new ServiceHost(typeof(AddService));
sh.AddServiceEndpoint(
typeof(AddIntPoint),
new WSHttpBinding(),
"http://localhost/AddService/Ep1");
sh.Open();
...
Следующий фрагмент кода иллюстрирует процесс отправки сообщений клиентом
оконечной точке AddIntPoint сервиса:
public class WCFClientApp
{
//инициализация канала передачи данных
public void SendMessageToEndpoint()
{
MathProxy proxy = new MathProxy();
int result = proxy.Add(35, 7);
}
}
Аналогичным образом клиент хранит свою оконечную точку для поддержки связи с
оконечной точной сервиса. Кстати говоря, сервисы могут предоставлять целую
коллекцию оконечных точек, а значит, предоставляют возможность использовать
несколько различных каналов передачи данных (транспортов) и методов. Это дает
возможность абстрагироваться от канала передачи данных и расширить множество
потенциальных клиентских платформ за счет использования различных протоколов
передачи данных. Например, ты можешь синхронизировать данные, поступающие с
твоего основного ботнета и ботнета, основанного исключительно на мобильных
платформах. Таким образом ты потенциально расширяешь спектр зараженных машин.
Например, ты можешь синхронизировать данные, поступающие с твоего
основного ботнета и ботнета, основанного исключительно на мобильных
платформах. Таким образом ты потенциально расширяешь спектр зараженных машин
Конфигурационный файл сервиса, расположенный вне исходного кода, позволяет
легко активировать/деактивировать дополнительные опции сервиса (настройки
безопасности, проверка целостности передаваемых данных и т.п.).
К не менее приятным особенностям WCF-сервисов также стоит отнести полную
независимость от IIS-сервера (в этом заключается отличие от обычных веб-сервисов,
работающих исключительно под его управлением). То есть мы можем поднять
консольное приложение в виде сервиса, работающего по HTTP-протоколу.
Что же там, за горизонтом?
К спектру технологий WCF можно подойти с разных позиций: разработка,
безопасность, масштабируемость. Охватить детали той или иной области, которой
касается Windows Communication Foundation, невозможно в рамках одной статьи. Да
мы такой задачи перед собой и не ставили. Рассмотрев детали быстрой организации
клиент-сервисной (именно сервисной) архитектуры, мы создали плацдарм для
дальнейших исследований и непосредственного испытания майкрософтоской технологии
в боевых условиях.
Распределение может быть полезно в любой окружающей нас области. Кто знает,
может быть повседневные вещи в распределенном состоянии окажутся намного более
удобными, и ты скажешь: "Как же я раньше до этого не додумался?". Вот, например,
взгляни на свои веб-шеллы. Вспомни, как быстро их палят и прикрывают. Задумайся,
почему? Потому что ты сам делаешь для этого все возможное: обращаясь каждый раз
к одному и тому же сомнительному скрипту по несколько раз за день, ты оставляешь
в логах веб-сервера избыточную информацию для бдительного администратора. А
теперь представь, насколько возрастет степень твоей анонимности и
конфиденциальность операций на вломанном сервере, если ты раскидаешь функционал
своего веб-шелла по его нескольким неприметным уголкам обращение его частям.
Предоставленный материал представляет собой лишь вводную часть к той длинной
истории, которая называется "WCF-сервис и сорок разбойников", коими выступают
придуманные тобою сервисы. Ознакомившись с теоретической составляющей и бегло
освоив базовые конструкции и детали конфигурации сервисной части, ты получаешь в
свое распоряжение мощный инструмент реализации своих самых распределенных идей.
Свои я уже реализовал и намерен поделиться ими с тобой на страницах нашего
журнала.
WWW
http://www.xakep.ru/post/52434/ – статья ".NET Remoting: программим
системы распределенных grid-вычислений".
http://www.techdays.ru/
– официальный ресурс "мелокомягких", где хранится огромное количество
информации по WCF.
http://defec.ru – мой ресурс,
где ты можешь задать вопросы и поделиться идеями.
DVD
На диске тебя ждет пример клиент-сервисного приложения. Рекомендую
разобраться в значении каждой строчки кода.