Text
                    Шаблоны интеграции
корпоративных
приложений
Проектирование, создание
и развертывание решений, основанных
на обмене сообщениями

Enterprise Integration Patterns Designing, Building, and Deploying Messaging Solutions Gregor Hohpe Bobby Wolf With Contributions by Kyle Brown Conrad F. D’Cruz Martin Fowler Sean Neville Michael J. Rettig Jonathan Simon ▼ ▼ ADDISON-WESLEY Boston San Francisco New York Toronto • Montreal London Munich Paris Madrid Capetown • Sydney Tokyo Singapore • Mexico City
Шаблоны интеграции корпоративных приложений Проектирование, создание и развертывание решений, основанных на обмене сообщениями Грегор Хоп Бобби Вульф при участии Кайла Брауна Конрада Ф. Д’Круза Мартина Фаулера Шона Невилла Майкла Дж. Реттига Джонатана Саймона Москва • Санкт-Петербург • Киев 2007
ББК 32.973.26-018.2.75 Х78 УДК 681.3.07 Издательский дом “Вильямс” Главный редактор С.Н. Тригуб Зав. редакцией В. Р. Гинзбург Перевод с английского и редакция А.В. Журавлева, Н.Н. Селиной По общим вопросам обращайтесь в Издательский дом “Вильямс” по адресу: info@williamspublishing.com, http://www.williamspublishing.com 115419, Москва, а/я 783; 03150, Киев, а/я 152 Хоп, Грегор, Вульф, Бобби. Х78 Шаблоны интеграции корпоративных приложений. : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2007. — 672 с.: ил. — Парал. тит. англ. ISBN 978-5-8459-1146-9 (рус.) В данной книге исследуются стратегии интеграции корпоративных приложений с помощью механизмов обмена сообщениями. Авторы рассматривают шаблоны проек- тирования и приводят практические примеры интеграции приложений, демонстри- рующие преимущества обмена сообщениями и эффективность решений, создаваемых на основе этой технологии. Каждый шаблон сопровождается описанием некоторой задачи проектирования, обсуждением исходных условий и представлением элегант- ного, сбалансированного решения. Авторы подчеркивают как преимущества, так и недостатки обмена сообщениями, а также дают практические советы по написанию кода подключения приложения к системе обмена сообщениями, маршрутизации сообщений и мониторинга состояния системы. Книга ориентирована на разработчиков программного обеспечения и системных интеграторов, использующих различные технологии и продукты для обмена сообще- ниями, такие как Java Message Service (JMS), Microsoft Message Queuing (MSMQ), IBM WebSphere MQ, Microsoft BizTalk, TIBCO, WebMethods, SeeBeyond, Vitrian др. ББК 32.973.26-018.2.75 Все названия программных продуктов являются зарегистрированными торговыми марками соответ- ствующих фирм. Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами, будь то электронные или механические, включая фо- токопирование и запись на магнитный носитель, если на это нет письменного разрешения издательства Addison-Wesley. Authorized translation from the English language edition published by Addison-Wesley, Copyright © 2004. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the publisher. Russian language edition is published by Williams Publishing House according to the Agreement with R&I Enterprises XmernauoiuA, Copyiigin^i . ISBN 978-5-8459-1146-9 (pyc.) ISBN 0-321-20068-3 (англ.) © Издательский дом “Вильямс”, 2007 © Pearson Education, Inc., 2004
Оглавление Введение 24 Глава 1. Решение задач интеграции с помощью шаблонов проектирования 43 Глава 2. Стили интеграции 77 Глава 3. Системы обмена сообщениями 91 Глава 4. Каналы обмена сообщениями 127 Глава 5. Построение сообщений 167 Глава 6. Практикум: простой пример обмена сообщениями 205 Глава 7. Маршрутизация сообщений 243 Глава 8. Преобразование сообщений 339 Глава 9. Практикум: сложный обмен сообщениями 373 Глава 10. Конечные точки обмена сообщениями 477 Глава 11. Управление системой 549 Глава 12. Практикум: управление системой 583 Глава 13. Шаблоны интеграции на практике 609 Глава 14. Кое-что в заключение 629 Приложение А. Список шаблонов проектирования 653 Приложение Б. Шаблоны интеграции корпоративных приложений 660 Основные источники информации 662 Предметный указатель 668
Содержание Введение 24 Что такое обмен сообщениями 25 Что такое система обмена сообщениями 26 Преимущества обмена сообщениями 27 Недостатки асинхронного обмена сообщениями 30 Мыслим асинхронно 31 Распределенное приложение или интеграция приложений 32 Коммерческие системы обмена сообщениями 32 Форма шаблонов 34 Диаграммы, использованные в книге 36 Примеры и практикумы 38 Как организована эта книга 39 С чего начать 40 Поддержка 41 Резюме 41 Глава 1. Решение задач интеграции с помощью шаблонов проектирования 43 Необходимость интеграции 43 Трудности интеграции 44 Роль интеграционных шаблонов проектирования 46 Типы интеграционных задач 46 Слабое связывание 50 Пример простой интеграции 51 Компоненты слабосвязанного интеграционного решения 55 Пример: “Приборы и устройства” 56 Внутренние системы 57 Размещение заказов 58 Обработка заказов 59 Проверка состояния заказа 65 Изменение адреса клиента 69 Обновление каталога товаров 71 Рассылка новостей 72 Тестирование и мониторинг 73 Резюме 75 Глава 2. Стили интеграции 77 Введение 77 Критерии интеграции приложений 77 Способы интеграции приложений 79 Передача файла (File Transfer) 80 Общая база данных (Shared Database) 83 Удаленный вызов процедуры (Remote Procedure Invocation) 85 Обмен сообщениями (Messaging) 87
Содержание 7 Глава 3. Системы обмена сообщениями 91 Введение 91 Основные концепции обмена сообщениями 91 Об организации книги 92 Канал сообщений (Message Channel) 93 Сообщение (Message) 98 Каналы и фильтры (Pipes and Filters) 102 Конвейерная обработка 104 Параллельная обработка 104 История архитектуры каналов и фильтров 105 Маршрутизатор сообщений (Message Router) 109 Типы маршрутизаторов сообщений 111 Транслятор сообщений (Message Translator) 115 Уровни преобразования 116 Уровни связывания 118 Цепочечные преобразования 118 Конечная точка сообщения (Message Endpoint) 124 Глава 4. Каналы обмена сообщениями 127 Введение 127 Основные вопросы, связанные с применением каналов обмена сообщениями 127 Решения 128 Канал “точка-точка” (Point-to-Point Channel) 131 Канал “публикация-подписка” (Publish-Subscribe Channel) 134 Канал типа данных (Datatype Channel) 139 Канал недопустимых сообщений (Invalid Message Channel) 143 Канал недоставленных сообщений (Dead Letter Channel) 147 Гарантированная доставка (Guaranteed Delivery) 149 Адаптер канала (Channel Adapter) 154 Мост обмена сообщениями (Messaging Bridge) 159 Шина сообщений (Message Bus) 162 Глава 5. Построение сообщений 167 Введение 167 Сообщение с командой (Command Message) 169 Сообщение с данными документа (Document Message) 171 Сообщение о событии (Event Message) 174 Запрос-ответ (Request- Reply) 177 Обратный адрес (Return Address) 182 Идентификатор корреляции (Correlation Identifier) 186 Цепочка сообщений (Message Sequence) 192 Срокдейстъия сообщения (Message Expiration) 198 Индикатор формата (Format Indicator) 201 Глава 6. Практикум: простой пример обмена сообщениями 205 Введение 205 Запрос-ответ 205
8 Содержание Публикация-подписка 206 Запрос-отает (JMS) 208 Описание 208 Код 210 Обработка сообщения недопустимого формата 216 Итог 217 Запрос-отает (.NET) 219 Описание 219 Код 221 Обработка сообщения недопустимого формата 225 Итог 226 Публикация-подписка (JMS) 227 Наблюдатель (Observer) 227 Наблюдатель (Observer) в распределенной среде 228 Публикация-подписка 229 Сравнение двух подходов 232 Модель с активным и пассивным источниками данных 233 Проектирование каналов 238 Итог 241 Глава 7. Маршрутизация сообщений 243 Введение 243 Простые маршрутизаторы 243 Составные маршрутизаторы 245 Архитектурные шаблоны 245 Выбор маршрутизатора сообщений 246 Маршрутизатор на основе содержимого (Content-Based Router) 247 Уменьшение зависимостей 249 Фильтр сообщений (Message Filter) 253 Фильтры с сохранением или без сохранения состояния 254 Функции фильтрации, встроенные в системы обмена сообщениями 255 Использование фильтров сообщений вместо маршрутизатора на основе содержимого 256 Динамический маршрутизатор (Dynamic Router) 259 Список получателей (Recipient List) 264 Надежность 267 Динамический список получателей 268 Эффективность с точки зрения сети 269 Список получателей или канал “публикация-подписка” с фильтрами сообщений 269 Разветвитель (Splitter) 274 Итеративные разветвители 275 Статические разветвители 276 Упорядоченные или неупорядоченные дочерние сообщения 277 Агрегатор (Aggregator) 283 Детали реализации 285 Стратегии агрегации 286 Преобразователь порядка (Resequencer) 297 Порядковый номер 298
Содержание 9 Внутреннее устройство 299 Борьба с переполнением буфера 300 Обработчик составного сообщения (Composed Message Processor) 307 Рассылка-сборка (Scatter-Gather) 310 Карта маршрутизации (Routing Slip) 314 Применение карты маршрутизации к унаследованным приложениям 319 Область применения 320 Реализация простого маршрутизатора с картой маршрутизации 320 Диспетчер процессов (Process Manager) 325 Управление состоянием 327 Экземпляры процесса 327 Корреляция 328 Сохранение состояния в сообщениях 329 Создание определения процесса 330 Сравнение диспетчера процессов с другими шаблонами 332 Брокер сообщений (Message Broker) 334 Глава 8. Преобразование сообщений 339 Введение 339 Устранение зависимостей 340 Управление метаданными 340 Преобразование данных в других схемах интеграции 341 Оболочка конверта (Envelope Wrapper) 342 Расширитель содержимого (Content Enricher) 348 Фильтр содержимого (Content Filter) 354 Квитанция (Claim Check) 358 Выбор ключа 360 Использование квитанции для сокрытия информации 361 Использование квитанции с диспетчером процессов 362 Нормализатор (Normalizer) 364 Определение формата сообщения 365 Каноническая модель данных (Canonical Data Model) 367 Способы преобразования 369 Двойное преобразование 370 Разработка канонической модели данных 370 Зависимости между форматами данных 371 Глава 9. Практикум: сложный обмен сообщениями 373 Пример: кредитный брокер 373 Выбор процентной ставки по кредиту 373 Проектирование потока сообщений 375 Режим выполнения операций: синхронный или асинхронный 377 Адресация: распределение или аукцион 378 Стратегии агрегации: несколько каналов или один 380 Управление одновременным доступом 380 Три реализации 381 Синхронная реализация с использованием Web-служб 383 Архитектура решения 383 Соображения по поводу проектирования Web-служб 384
10 Содержание Набор средств Apache Axis 387 Поиск расположения службы 390 Приложение кредитного брокера 391 Компоненты приложения кредитного брокера 393 Клиентское приложение 409 Запуск решения 410 Ограничения производительности 412 Ограничения данного примера 412 Резюме 413 Асинхронная реализация с использованием MSMQ 414 Экосистема локального брокера 414 Закладываем основы: шлюз обмена сообщениями 415 Базовые классы для общей функциональности 418 Компонент банка 423 Компонент кредитного бюро 425 Компонент кредитного брокера 426 Оптимизация кода кредитного брокера 445 Запуск системы 448 Повышение производительности 449 Несколько слов о тестировании 453 Ограничения данного примера 456 Резюме 457 Асинхронная реализация с использованием Т1ВСО ActiveEnterprise 458 Архитектура решения 458 Набор средств, используемых для реализации 460 Интерфейсы 464 Реализация синхронных служб 465 Процесс кредитного брокера 468 Управление параллельными аукционами 472 Выполнение 473 Резюме 475 Глава 10. Конечные точки обмена сообщениями 477 Введение 477 Шаблоны отправки и получения сообщений 477 Шаблоны потребителей сообщений 478 Некоторые аспекты реализации конечных точек 480 Шлюз обмена сообщениями (Messaging Gateway) 482 Соединение шлюзов в цепочки 486 Обработка исключений системы обмена сообщениями 486 Генерация кода шлюзов 487 Использование шлюзов в процессе тестирования 487 Преобразователь обмена сообшениями (Messaging Mapper) 491 Упрощение кодирования 495 Преобразователь или транслятор 495 Транзакционный клиент (Transactional Client) 498 Опрашивающий потребитель (Polling Consumer) 507 Событийно управляемый потребитель (Event-Driven Consumer) 511 Конкурирующие потребители (Competing Consumers) 515
Содержание 11 Диспетчер сообщений (Message Dispatcher) 521 Избирательный потребитель (Selective Consumer) 528 Постоянный подписчик (Durable Subscriber) 535 Идемпотентный получатель (Idempotent Receiver) 541 Активатор службы (Service Activator) 545 Глава 11. Управление системой 549 Введение 549 Мониторинг и управление 550 Наблюдение и анализ трафика сообщений 550 Тестирование и отладка 551 Шина управления (Control Bus) 552 Обходной путь (Detour) 556 Отвод (Wire Тар) 558 Журнал доставки сообщения (Message History) 561 Хранилище сообщений (Message Store) 565 Интеллектуальный заместитель (Smart Proxy) 567 Тестовое сообщение (Test Message) 577 Вентиль канала (Channel Purger) 579 Глава 12. Практикум: управление системой 583 Управление системой кредитного брокера 583 Оснащение кредитного брокера средствами контроля 583 Управляющая консоль 584 Качество обслуживания кредитного брокера 585 Проверка функциональности кредитного бюро 592 Перемещение при сбое кредитного бюро 598 Усовершенствование управляющей консоли 600 Ограничения примера, приведенного в этой главе 607 Глава 13. Шаблоны интеграции на практике 609 Практикум: система формирования цен на облигации 609 Построение системы 610 Архитектура с учетом шаблонов 610 Структура каналов 616 Выбор канала сообщений 620 Решение проблемы с помощью шаблонов 623 Мигающие ячейки 623 Сбой системы в процессе работы 625 Резюме 628 Глава 14. Кое-что в заключение 629 Новые стандарты и перспективы интеграции корпоративных приложений 629 Связь между стандартами и шаблонами проектирования 630 Основные организации, занимающиеся утверждением стандартов 631 Компоненты бизнес-процессов и внутренний обмен сообщениями между Web-службами 633 ebXML и ebMS 635 BPEL4WS 638
12 Содержание WSCI 640 Стандарты компонентов бизнес-процессов для Java 641 Спецификации WS-* 643 Заключение 651 Приложение А. Список шаблонов проектирования 653 Приложение Б. Шаблоны интеграции корпоративных приложений 660 Основные источники информации 662 Предметный указатель 668
Моей семье и всем моим друзьям, которые поддерживали меня во время написания этой книги. —Грегор Шэрон, моей любящей жене. —Бобби
Предисловие Джона Крупи Как вы реагируете на появление новой технологии? Вы изучаете ее. Столкнувшись с плат- формой J2EE, я не нашел ничего лучшего, кроме как обратиться к ее спецификациям (книг по J2EE на то время еще не существовало). В частности, я сконцентрировал свое внимание на подмножестве J2EE— технологии EJB. Тем не менее изучение технологии является лишь первым шагом к ее эффективному применению. Преимущество платформенных тех- нологий состоит в том, что они ограничивают разработчика определенным кругом задач. К сожалению, это не исключает неверного применения самой технологии. По моим наблюдениям, за последние 15 лет в умах разработчиков программного обеспечения прочно укоренились идеи эффективного программирования и проектирова- ния. В настоящее время на рынке существует огромное количество книг по программи- рованию на Java и С#, однако гораздо меньше по проектированию приложений. Написав книгу Core J2EE Patterns, мы с Дипаком Алуром (Deepak Alur) и Дэном Малксом (Dan Malks) хотели помочь 12ЕЕ-разработчикам в создании более эффективного кода. Основ- ная идея нашей книги заключалась в использовании шаблонов проектирования. Как от- метил Джеймс Бейти (James Baty), главный инженер компании Sun Microsystems, “шаблоны являются краеугольным камнем проектирования”. Я полностью согласен с этим высказыванием. К счастью, так же считают и авторы настоящей книги. Книга, которую вы держите в руках, посвящена чрезвычайно популярной в последнее время теме: интеграции приложений с помощью обмена сообщениями. На мой взгляд, идея обмена сообщениями найдет свое применение не только при интеграции приложе- ний, но и при создании Web-служб. Как это было на заре появления технологий J2EE и .NET, вопросам проектирования Web-служб уделяется пока еще очень мало внимания. Многие считают, что Web-службы являются всего лишь новым способом решения суще- ствующих задач интеграции, и я полностью с этим согласен. Тем не менее это не отменя- ет необходимость проектирования самих Web-служб. Изюминка данной книги состоит в наличии большого количества шаблонов, которые можно применять при проектирова- нии Web-служб и других интеграционных систем. Бобби и Грегор не балуют читателя конкретными примерами спецификаций Web-служб, поскольку они все еще нуждаются в доработке и утверждении. Впрочем, это вполне простительно. Подлинная ценность книги проявится после объявления соответствующих спецификаций стандартами, что позволит использовать предложенные шаблоны проектирования для разработки соответ- ствующих этим стандартам приложений. Вполне вероятно, что создание архитектур, ориентированных на использование служб, станет основным способом интеграции при- ложений в ближайшем будущем. Прочтите эту книгу от начала до конца. Она способна кардинально изменить вашу карьеру. Джон Крупи Бетесда, Мэриленд Август 2003 г.
Предисловие Мартина Фаулера В процессе написания книги Patterns of Enterprise Application Architecture (Фаулер M. Архи- тектура корпоративных программных приложений.— М.: Издательский дом “Вильямс”, 2004) мне посчастливилось получить подробную рецензию на включенный в нее матери- ал от Кайла Брауна (Kyle Brown) и Рейчел Рейниц (Rachel Reinitz). В результате нескольких неофициальных встреч в офисе Кайла в Роли-Дарем мы пришли к выводу, что самым существенным пробелом моей книги стали системы асинхронного обмена сообщениями. Безусловно, моя книга содержит множество пробелов и не претендует на звание исчерпывающего источника информации по шаблонам проектирования корпоративных приложений. Тем не менее отсутствие в ней описания систем асинхронного обмена сообщениями особенно болезненно ввиду того, что эти системы будут играть ключевую роль при решении задач интеграции. Приложения не могут существовать обособленно одно от другого, и нам нужны методики, позволяющие наладить связь между приложе- ниями, изначально не предусматривавшими возможность взаимодействия. На сегодняшний день существует множество различных технологий интеграции при- ложений. На мой взгляд, наиболее многообещающей из них является обмен сообщения- ми. Организация эффективного обмена сообщениями— нетривиальная задача, слож- ность которой обусловливается асинхронной природой сообщений, а также различиями в подходах к асинхронному программированию. К сожалению, мне не хватило времени, сил и, что самое главное, знаний, чтобы дос- тойно раскрыть тему обмена сообщениями в Patterns of Enterprise Application Architecture. Тем не менее я все-таки нашел решение этой проблемы в виде Грегора и Бобби, взяв- шихся за написание книги, которую вы сейчас держите в руках. Следует отметить, что авторы блестяще справились с поставленной перед ними зада- чей. Если вы уже работали с системами обмена сообщениями, настоящая книга поможет вам систематизировать накопленный опыт и знания. Если же вы только приступаете к изучению данной темы, книга поспособствует закладке прочного фундамента, который пригодится вам при использовании любой технологии обмена сообщениями. Мартин Фаулер Мелроуз, Массачусетс Август 2003 г.
Вступление Эта книга посвящена интеграции корпоративных приложений с помощью обмена сооб- щениями. В ней не рассматриваются конкретные технологии или продукты. Вместо этого она ориентирована на разработчиков и интеграторов, использующих различные технологии и продукты для обмена сообщениями, такие как: • МОМ- и EAI-решения IBM WebSphere MQ, Microsoft BizTalk, TIBCO, WebMethods, SeeBeyond, Vitrian др.; • реализации спецификации Java Message Service (JMS), внедренные в серверы при- ложений J2EE, а также в отдельные продукты; • служба Microsoft Message Queuing (MSMQ), доступная через различные API, например через классы пространства имен Microsoft .NET System. Messaging; • новые стандарты Web-служб, поддерживающие асинхронный обмен сообщениями (например, WS-ReliableMessaging), а также соответствующие API, такие как Java API for XML Messaging (JAXM) от Sun Microsystems или Web Services Extensions (WSE) от Microsoft. Интеграция корпоративных приложений означает нечто большее, чем создание рас- пределенного приложения с я-уровневой архитектурой. Тогда как отдельный уровень распределенного приложения не может выполняться самостоятельно, интегрированные приложения представляют собой независимые сущности, способные к взаимной коор- динации по принципу слабой связи. Обмен сообщениями позволяет нескольким прило- жениям передавать данные и команды по сети в соответствии с подходом “отправил и забыл”. Последнее позволяет вызывающему приложению отправить информацию и вернуться к выполнению текущей задачи, переложив всю ответственность за доставку информации на систему обмена сообщениями. При необходимости вызывающее прило- жение может быть уведомлено о результате доставки информации с помощью функции обратного вызова. Несмотря на то что по сравнению с синхронным обменом сообще- ниями асинхронный подход способен усложнить проектирование приложения, возмож- ность неограниченного числа повторов асинхронного вызова способна существенно повысить надежность коммуникаций. Асинхронный обмен сообщениями обладает и другими преимуществами, такими как регулирование числа запросов и балансировка нагрузки.
Вступление 17 Для кого предназначена эта книга Эта книга призвана помочь разработчикам приложений и системным интеграторам нала- дить взаимодействие между приложениями с помощью средств, ориентированных на обмен сообщениями. В первую очередь, она предназначена для следующих специалистов. • Архитекторы и разработчики, проектирующие и создающие сложные корпоративные приложения, которые нуждаются в интеграции с другими приложениями. Мы ори- ентируемся на разработчиков приложений, использующих современные платфор- мы, такие как Java 2 Enterprise Edition (J2EE) и Microsoft .NET. С помощью этой книги вы научитесь соединять приложение с уровнем обмена сообщениями для взаимодействия с другими приложениями. Следует отметить, что предметом рас- смотрения этой книги является исключительно интеграция приложений, а не их создание. Шаблоны проектирования, применяющиеся при создании корпоратив- ных приложений, рассматриваются в книге Мартина Фаулера Patterns of Enterprise Application Architecture (Фаулер M. Архитектура корпоративных программных при- ложений. — М.: Издательский дом “Вильямс”, 2004). • Архитекторы и разработчики, проектирующие и создающие интеграционные решения, предназначенные для налаживания взаимодействия между пользовательскими приложениями. Вероятно, большинство читателей этой книги уже сталкивались с коммерческими средствами интеграции приложений, такими как IBM WebSphere MQ, TIBCO, WebMethods, See Beyond, Vitria и др. Каждое из этих средств содержит реализацию многих шаблонов проектирования, представленных в книге. Помимо фундаментальных концепций, стоящих за интеграцией приложений, принимать правильные решения при проектировании вам поможет универсальный язык шаблонов, не зависящих от конкретного вендора. • Корпоративные архитекторы, в обязанности которых входит мониторинг про- граммных и аппаратных активов предприятия. Язык и графическое представление шаблонов проектирования помогут описать крупномасштабные решения инте- грации, охватывающие множество различных технологий. Кроме того, язык шаб- лонов поможет наладить эффективное взаимодействие между корпоративным ар- хитектором и архитекторами/разработчиками корпоративных приложений и ре- шений интеграции. Чему учит эта книга Основное назначение этой книги — познакомить читателя с принципами проектиро- вания успешных решений интеграции корпоративных приложений. В процессе ее чтения вы узнаете: • преимущества и ограничения асинхронного обмена сообщениями в сравнении с другими технологиями интеграции; • как определить каналы обмена сообщениями, в которых нуждается приложение; регламентировать процедуру получения одного и того же сообщения несколькими потребителями; обрабатывать сообщения неправильного формата;
18 Вступление • когда следует отправлять сообщение, какую информацию оно должно содержать и как использовать специальные свойства сообщений; • как доставить сообщение в конечную точку его назначения (в том числе и при отсутствии информации о получателе сообщения); • как преобразовать сообщение при несовпадении формата отправителя и получателя; • как спроектировать код соединения приложения с системой обмена сообщениями; • как проводить управление и мониторинг системы обмена сообщениями. Что не рассматривается в этой книге На наш взгляд, все книги, в названиях которых встречается слово “корпоративный”, делятся на три категории. К первой категории относятся книги, авторы которых стара- ются всецело охватить предмет обсуждения, однако в конечном итоге останавливаются на подробном рассмотрении конкретных решений. Книги второй категории содержат практические советы по разработке конкретных решений, ограничивая при этом диапа- зон рассматриваемого материала. Наконец, можно попытаться написать книгу, объеди- няющую в себе лучшие характеристики первых двух категорий, однако в этом случае она либо не будет закончена, либо будет опубликована настолько поздно, что потеряет свою актуальность. Настоящая книга относится ко второй категории. Мы попытались напи- сать книгу о создании интеграционных решений, пожертвовав при этом некоторыми смежными темами. В частности, мы не рассматривали вопросы безопасности, сложного отображения данных, рабочих потоков, механизма поддержки правил, масштабируемо- сти, устойчивости, а также распределенной обработки транзакций (продукты ХА, Tuxedo и др.). Асинхронный обмен сообщениями был выбран основной темой книги по нес- кольким причинам. Во-первых, это одна из наиболее перспективных технологий интег- рации приложений, которой свойственно множество интереснейших вопросов проекти- рования. Во-вторых, рассмотрение асинхронного обмена сообщениями позволяет абст- рагироваться от реализации конкретных решений интеграции, предлагаемых различны- ми вендорами. Эта книга не является руководством по конкретной технологии обмена сообщениями или межплатформенному решению. Чтобы подчеркнуть многообразие концепций, пред- ставленных в книге, мы включили в нее примеры использования целого ряда различных технологий, таких как JMS, MSMQ, TIBCO, BizTalk и XSL. Каждая из перечисленных технологий рассматривалась исключительно в аспекте принятия решений проектирова- ния и возникающих при этом компромиссов. Для подробного изучения какой-либо из технологий интеграции приложений обратитесь к источникам, перечисленным в конце книге, или к ресурсам Интернета. Структура книги Как следует из названия книги, большая ее часть посвящена шаблонам. Шаблоны — это проверенный способ представления накопленного опыта и знаний в таких областях, как архитектура программных приложений, объектно-ориентированное проектирование и создание интеграционных решений с помощью технологий обмена сообщениями.
Вступление 19 Каждый шаблон состоит из описания некоторой проблемы проектирования, обсуж- дения исходных условий и представления элегантного, сбалансированного решения. В большинстве случаев предлагаемое решение является результатом длительного процес- са поиска. Каждый шаблон “вбирает” в себя опыт, накопленный старшими разработчи- ками и архитекторами в попытке дать оптимальный ответ на конкретную задачу интегра- ции. Хотим подчеркнуть, что в этой книге нет “придуманных” нами шаблонов. Шаблон нельзя “придумать”; к нему можно прийти в результате длительных “полевых” испыта- ний, извлекая уроки из собственных ошибок. Если вы уже имеете опыт работы со средствами интеграции корпоративных приложе- ний и с архитектурой асинхронного обмена сообщениями, то большинство из представ- ленных в этой книге шаблонов наверняка покажутся вам до боли знакомыми. Однако даже в этом случае она может принести немалую пользу. Чтение книги поможет закре- пить знания, накопленные в результате использования технологий обмена сообщениями, а также поспособствует развитию привычки документирования создаваемых решений и взаимоотношений между ними. Благодаря универсальному языку шаблонов вы сможе- те наладить эффективное взаимодействие со своими коллегами. Представленные в книге шаблоны можно реализовать с помощью различных плат- форм и языков программирования. Чтобы облегчить процесс встраивания шаблона в конкретную среду, в книгу были включены примеры реализации шаблонов с привлече- нием нескольких популярных технологий, таких как JMS, MSMQ, TIBCO, BizTalk, XSL и др. Кроме того, мы продемонстрировали примеры создания целостных решений, осно- ванных на сочетании шаблонов проектирования. Интеграция корпоративных приложений с помощью архитектуры асинхронного об- мена сообщениями— сложная и увлекательная задача. Искренне надеемся, что наша книга поможет вам блестяще решить ее. О фотографии на обложке книги На обложках всех книг серии A Martin Fowler Signature Book размещается фотография какого-либо моста. В некотором смысле нам повезло, так как мост великолепно иллюст- рирует идею интеграции. На протяжении тысячелетий мосты помогали человеку преодо- левать препятствия в виде рек, горных ущелий и оживленных автострад. Мост Тайко-баси (“Барабанный мост”) перекинут через пруд перед храмом Сумиёси- тайся, расположенным в Осаке, Япония. Мы выбрали этот мост за его красоту и элегант- ность. Синтоистский храм Сумиёси-тайся был построен на берегу бухты Нанива в III веке н.э. и посвящен божествам, которые оберегали моряков, отправлявшихся в плавание. За много лет вода отступила, и сейчас храм удален от воды более чем на 5 км. В начале каждого года Сумиёси-тайся посещают более трех миллионов человек. Грегор Хоп Сан-Франциско, Калифорния Бобби Вульф Роли, Северная Каролина Сентябрь 2003 г. ww. enterpriseintegrationpattems. сот
20 Вступление Ждем ваших отзывов! Вы, читатель этой книги, и есть главный ее критик. Мы ценим ваше мнение и хотим знать, что было сделано нами правильно, что можно было сделать лучше и что еще вы хо- тели бы увидеть изданным нами. Нам интересны любые ваши замечания в наш адрес. Мы ждем ваших комментариев и надеемся на них. Вы можете прислать нам бумажное или электронное письмо либо просто посетить наш Web-сервер и оставить свои замеча- ния там. Одним словом, любым удобным для вас способом дайте нам знать, нравится ли вам эта книга, а также выскажите свое мнение о том, как сделать наши книги более интересными для вас. Отправляя письмо или сообщение, не забудьте указать название книги и ее авторов, а также свой обратный адрес. Мы внимательно ознакомимся с вашим мнением и обяза- тельно учтем его при отборе и подготовке к изданию новых книг. Наши электронные адреса: E-mail: info@williamspublishing. com WWW: http://www .will iamspubl i shing. com Наши почтовые адреса: в России: в Украине: 115419, Москва, а/я 783 03150, Киев, а/я 152
Д-р Карл Саган, “Послание внеземным формам жизни” (табличка, отправленная в космос на американском аппарате серии “Пионер”)
Благодарности Работа над этой книгой отняла у ее авторов немало времени и сил. Идея создания книги о шаблонах интеграции, основанных на обмене сообщениями, впервые возникла в 2001 году в процессе написания Мартином Фаулером своего бестселлера Patterns of Enterprise Application Architecture (Фаулер M. Архитектура корпоративных программных приложений. — М.: Издательский дом “Вильямс”, 2004). Кайл Браун (Kyle Brown), один из рецензентов Patterns of Enterprise Application Architecture, заметил, что в книге Мартина практически не освещается тема интеграции приложений. Этот пробел стал основным предметом обсуждения на нескольких встречах между Мартином и Кайлом, на которых присутствовали также Рейчел Рейниц (Rachel Reinitz), Джон Крупи (John Crupi) и Марк Вайцель (Mark Weitzel). Осенью 2001 года к дискуссии присоединился Бобби, а зимой 2002 года— Грегор. Летом 2002 года группа единомышленников представила на конфе- ренции по языкам шаблонов программ (Pattern Languages of Programs— PLoP) две рабо- ты, одна из которых была написана Бобби и Кайлом, а другая—Грегором. После конфе- ренции Кайл и Мартин сосредоточились на собственных проектах, а Грегор и Бобби ре- шили объединить свои статьи для создания фундамента будущей книги. Примерно в это же время был открыт сайт www.enterpriseintegrationpattems.com, посредством которого ар- хитекторы и разработчики интеграционных решений всего мира могли принять участие в совместной работе над содержимым книги. Впоследствии к написанию книги были при- влечены несколько соавторов. Спустя два года, прошедших с момента критического за- мечания Кайла относительно содержимого Patterns of Enterprise Application Architecture, ру- копись настоящей книги была передана издателю. Эта книга является плодом совместной работы огромного числа людей. Коллеги и друзья (многих из которых мы приобрели в процессе написания книги) подавали идеи для размещаемых в книге примеров, проверяли корректность материала с технической точки зрения, а также снабжали нас бесценными советами и критикой. Отдельной благодарности заслуживают Кайл Браун и Мартин Фаулер— инициаторы создания этой книги. Если бы Мартин не принялся писать Patterns of Enterprise Application Architecture, а Кайл не сформировал группу для обсуждения шаблонов интеграции с помо- щью обмена сообщениями, наша книга могла бы никогда не увидеть свет. Огромный вклад в создание книги внесли ее соавторы: Конрад Ф. Д’Круз (Conrad F. D’Cruz), Шон Невилл (Sean Neville), Майкл Дж. Реттиг (Michael J. Rettig) и Джонатан Саймон (Jonathan Simon). Написанные ими главы помогли пролить свет на практиче- скую сторону применения шаблонов проектирования. Одними из первых критиков книги стали участники конференции по языкам шаблонов программ PLoP2002: Али Арсанджани (Ali Arsanjani), Кайл Браун, Джон Крупи, Эрик Эванс (Eric Evans), Мартин Фаулер, Брайан Мэрик (Brian Marick), Тоби Сарвер (Toby Sarver), Джонатан Саймон, Билл Транделл (Bill Trundell) и Марек Вокач (Marek Vokac).
Благодарности 23 Мы хотели бы поблагодарить рецензентов, множество раз перечитавших черновик книги и снабдивших нас сотней полезных советов: • Ричарда Хелма (Richard Helm), • Люка Хохманна (Luke Hohmann), • Драгоша Манолеску (Dragos Manolescu), • Дэвида Райса (David Rice), • Русс Руфер (Russ Rufer) и всех членов Silicon Valley Patterns Group, • Мэтью Шорта (Matthew Short). Отдельное спасибо Русс за привлечение к работе над книгой сообщества Silicon Valley Patterns Group. Вклад этих людей был поистине неоценим: Роберт Бенсон (Robert Benson), Трейси Бялик (Tracy Bialik), Джеффри Блейк (Jeffrey Blake), Азад Болур (Azad Bolour), Джон Брюэр (John Brewer), Боб Эванс (Bob Evans), Энди Фарли (Andy Farlie), Джефф Глаза (Jeff Glaza), Фил Гудвин (Phil Goodwin), Алан Харриман (Alan Hamman), Кен Хеджмановски (Ken Hejmanowski), Дебора Кадда (Deborah Kaddah), Ритурадж Кир- ти (Rituraj Kirti), Ян Луни (Jan Looney), Крис Лопес (Chris Lopez), Джерри Луис (Jerry Louis), Тао-хунг Ma (Tao-hung Ма), Джефф Миллер (Jeff Miller), Стилян Пандев (Stilian Pandev), Джон Парелло (John Parello), Хема Пиллей (Hema Pillay), Русс Руфер, Рич Смит (Rich Smith), Кэрол Тислтуэйт (Carol Thistlethwaite), Дебби Утли (Debbie Utley), Уолтер Ваннини (Walter Vannini), Дэвид Выдра (David Vydra) и Тед Янг (Ted Young). Список рассылки Web-сайта www.enterpriseintegrationpattems.com позволил принять участие в обсуждении материала книги всем желающим. Наибольший вклад в дискуссию внес Билл Транделл. Среди самых активных участников списка рассылки оказались так- же Венкатешвар Бомминени (Venkateshwar Bommineni), Данкан Крэгг (Duncan Cragg), Джон Крупи, Фокко Дегенаар (Fokko Degenaar), Шаилеш Госави (Shailesh Gosavi), Кри- стиан Холл (Christian Hall), Ральф Джонсон (Ralph Johnson), Пол Джулиус (Paul Julius), Орьян Люндберг (Oijan Lundberg), Драгош Манолеску, Роб Ми (Rob Мее), Шрикант Нарасимхан (Srikanth Narasimhan), Майкл Реттиг, Фрэнк Зауэр (Frank Sauer), Джонатан Саймон, Федерико Спинацци (Federico Spinazzi), Рэнди Стаффорд (Randy Stafford), Марек Вокач, Джо Уолнз (Joe Walnes) и Марк Вайцель. Спасибо Мартину Фаулеру за то, что он позволил нам опубликовать книгу в серии A Martin Fowler Signature Book. Поддержка Мартина придала нам дополнительные силы, необходимые для завершения работы над книгой. Мы благодарны Джону Крупи за написанное им предисловие. На протяжении всего времени работы над книгой Джон был нашим советчиком и вдохновителем, проявляя при этом незаурядное терпение и прекрасное чувство юмора. Наконец мы хотели бы выразить огромную признательность замечательным сотруд- никам издательства Addison-Wesley: главному редактору Майку Хендриксону (Mike Hendrickson), руководителю производства Эми Флейшер (Amy Fleischer), руководителю проекта Ким Арни Малкахи (Kim Arney Mulcahy), литературному редактору Кэрол Дж. Ло- лье (Carol J. Lallier), корректору Ребекке Райдер (Rebecca Rider), составителю предмет- ного указателя Шэрон Хильгенберг (Sharon Hilgenberg), а также Жаклин Дюсетт (Jacquelyn Doucette), Джону Фуллеру (John Fuller) и Бернарду Гаффни (Bernard Gaffney). Мы наверняка забыли упомянуть несколько имен, имевших непосредственное отно- шение к появлению Enterprise Integration Patterns на свет. Простите нас за это, и еще раз огромное спасибо за помощь. Надеемся, что все вы так же гордитесь этой книгой, как и мы.
Введение Корпоративные приложения не могут существовать обособленно одно от другого. Про- грамма, установленная в магазине розничной продажи, не будет эффективной без взаи- модействия с программой, установленной на складе, а календарь на КПК— без синхро- низации с сервером расписаний. Как правило, разработчики интеграционных решений сталкиваются со следующими вызовами. • Ненадежность сети передачи данных. Все интеграционные решения предполагают передачу информации между устройствами. В отличие от процессов, выполняю- щихся в пределах одного компьютера, распределенной вычислительной среде присущ целый ряд недостатков. Зачастую общающиеся системы разделены кон- тинентами, что вынуждает передавать данные по телефонным линиям, сегментам локальных сетей, через маршрутизаторы, коммутаторы, общедоступные сети и спутниковые каналы связи. Доставка информации на каждом из этих этапов связана с задержкой и риском потери. • Низкая скорость передачи данных. Время доставки данных через компьютерную сеть на порядок больше времени вызова локального метода. Таким образом, соз- дание распределенного приложения требует применения иных принципов проек- тирования, чем создание приложения, выполняющегося в пределах одного ком- пьютера. • Различия между приложениями. Интеграционное решение должно учитывать все различия (язык программирования, платформа, формат данных), существующие между объединяемыми системами. • Неизбежность изменений. Интеграционное решение должно иметь возможность адаптации к изменению объединяемых им приложений. Зачастую преобразования в одной системе влекут за собой непредсказуемые последствия для других систем. Поэтому при интеграции приложений важно уменьшить их взаимозависимость за счет так называемого слабого связывания. Для преодоления описанных выше трудностей можно воспользоваться четырьмя основными подходами. 1. Передача файла (file Transfer, с. 80). Одно приложение создает файл, а другое при- ложение считывает его. Приложения должны согласовать имя файла, его распо- ложение, формат, время записи/считывания, а также процедуру удаления. 2. Общая база данных (Shared Database, с. 83). Несколько приложений используют общую логическую структуру данных, которой соответствует одна физическая ба- за данных. Наличие единого хранилища данных устраняет проблему передачи информации между приложениями.
Введение 25 3. Удаленный вызов процедуры (Remote Procedure Invocation, с. 85). Приложение пре- доставляет доступ к части своей функциональности посредством удаленного вы- зова процедуры. Взаимодействие между приложениями осуществляется синхрон- но в режиме реального времени. 4. Обмен сообщениями (Messaging, с. 87). Приложение размещает сообщение в общем канале, которое затем считывается другим приложением. Приложения должны согласовать канал, а также формат сообщения. Взаимодействие между приложе- ниями осуществляется в асинхронном режиме. Каждый из предложенных подходов имеет собственные преимущества и недостатки. На практике приложения могут быть интегрированы несколькими способами таким об- разом, чтобы использовать только сильные стороны того или иного подхода. Что такое обмен сообщениями Эта книга посвящена интеграции приложений с помощью обмена сообщениями. Чтобы лучше понять смысл обмена сообщениями, рассмотрим систему телефонной свя- зи. Телефонный разговор является ярким примером синхронного взаимодействия. Або- нент может начать общение с вызываемой стороной только в том случае, если последняя окажется свободной в момент звонка. Привнесение в эту систему автоответчика делает ее асинхронной. Если абонент не отвечает, ему можно оставить голосовое сообщение, которое он сможет прослушать в удобное для него время. Это намного проще, чем пы- таться дозвониться до абонента вновь и вновь. “Сохранение” части телефонного разго- вора в виде сообщения и помещение его в очередь для последующего прослушивания наглядно иллюстрирует сущность обмена сообщениями. Обмен сообщениями—это технология высокоскоростного асинхронного взаимодей- ствия между программами с гарантией доставки информации. Программы взаимодейст- вуют между собой, обмениваясь пакетами данных, называемыми сообщениями. Канал, или очередь, — это логический маршрут, объединяющий программы и использующийся для транспортировки сообщений. Канал напоминает массив сообщений, доступный для одновременного использования многими приложениями. Отправитель, или постав- щик, — это программа, отправляющая сообщение путем его размещения в канале. Полу- чатель, или потребитель, — это программа, получающая (а затем удаляющая) сообщение путем его считывания из канала. Сообщение представляет собой некоторую структуру данных— строку, байтовый массив, запись или объект. Оно может быть интерпретировано непосредственно как со- держащиеся в нем данные, как команда, которую необходимо выполнить получателю, или как описание события, произошедшего на стороне отправителя. Сообщение состоит из двух частей— заголовка и тела. Заголовок сообщения содержит метаданные (кто от- правил сообщение, куда его следует передать и т.п.), которые используются системой об- мена сообщениями и игнорируются получателем сообщения. Тело сообщения содержит полезную информацию, которая, как правило, игнорируется системой обмена сообще- ниями. Упоминая сообщение в разговоре, разработчик приложения обычно имеет в виду информацию, содержащуюся в теле сообщения.
26 Введение По сравнению с тремя оставшимися способами интеграции приложений, опыт рабо- ты с системами обмена сообщениями имеет весьма ограниченное число разработчиков. Как следствие применение архитектуры асинхронного обмена сообщениями зачастую требует переосмыслить подход к созданию приложений. Что такое система обмена сообщениями Функциональная часть обмена сообщениями обеспечивается отдельной программной системой, называемой системой обмена сообщениями или связующим ПО, ориентированным на обмен сообщениями (message-oriented middleware — МОМ). Система обмена сообщениями имеет много общего с системой баз данных. В частности, схеме базы данных, использую- щейся для определения формата хранимой информации, соответствуют каналы обмена со- общениями. Основная задача системы баз данных—- обеспечить надежное хранение ин- формации, а основная задача системы обмена сообщениями— гарантировать доставку со- общений с компьютера отправителя на компьютер получателя. Необходимость наличия системы обмена сообщениями обусловливается ненадежно- стью сетей передачи данных. Сбой в компьютерной сети— одна из самых распростра- ненных причин неудавшейся доставки сообщения от отправителя к получателю. Система обмена сообщениями позволяет гарантировать доставку информации за счет повторной отправки сообщения (до тех пор, пока оно не будет принято получателем). В идеальных условиях сообщение доставляется с первого раза, однако, к сожалению, так бывает дале- ко не всегда. Процедура передачи сообщения от отправителя к получателю состоит из пяти основных этапов. 1. Создание. Отправитель создает сообщение, содержащее полезную информацию. 2. Отправка. Отправитель помещает сообщение в канал. 3. Доставка. Система обмена сообщениями доставляет сообщение с компьютера от- правителя на компьютер получателя. 4. Получение. Получатель извлекает сообщение из канала. 5. Обработка. Получатель считывает полезную информацию. На рис. 1 проиллюстрированы все основные этапы процедуры передачи сообщения.
Введение 27 Рис. 1. Основные этапы передачи сообщения от отправителя к получателю с использованием системы обмена сообщениями На рис. 1 также отражены две важные концепции обмена сообщениями. 1. “Отправить и забыть”. Поместив сообщение в канал на этапе 2, отправитель может не заботиться о его дальнейшей судьбе—гарантированную доставку сооб- щения получателю обеспечивает система обмена сообщениями. 2. Передача с промежуточным хранением. На этапе 2 система обмена сообщениями со- храняет сообщение, помещенное отправителем в канал, на компьютере отправителя (в оперативной памяти или на жестком диске). На этапе 3 система обмена сообще- ниями доставляет сообщение с компьютера отправителя на компьютер получателя и сохраняет его на компьютере получателя. Процесс передачи сообщения с промежу- точным хранением повторяется, если для достижения компьютера получателя со- общение должно пройти через несколько других компьютеров. В описанной выше схеме этапы создания, отправки, получения и обработки сообще- ния могут показаться излишними. Действительно, почему бы просто не передать нужную информацию от отправителя к получателю? Создание сообщения и его передача системе обмена сообщениями позволяет делегировать последней всю ответственность за доставку данных, тем самым обеспечив надежную передачу единственной копии полезной ин- формации получателю. Преимущества обмена сообщениями Обмен сообщениями обладает множеством преимуществ по сравнению с другими технологиями интеграции приложений. Коротко говоря, обмен сообщениями более быстр, чем передача файла (File Transfer, с. 80), обладает лучшей инкапсуляцией по срав- нению с общей базой данных (Shared Database, с. 83) и более надежен, чем удаленный вызов процедуры (Remote Procedure Invocation, с. 85).
28 Введение Ниже перечислены дополнительные преимущества, которые позволяет получить тех- нология обмена сообщениями. • Удаленное взаимодействие. Обмен сообщениями позволяет наладить взаимодействие между отдельными приложениями. Два объекта, относящихся к одному и тому же процессу, могут совместно использовать данные, размещенные в оперативной памя- ти. Передача информации с одного компьютера на другой требует выполнения “сериализации” данных— преобразования соответствующих объектов в байтовый поток с целью последующей отправки по сети. Как было сказано выше, приложение может делегировать всю ответственность за передачу данных системе обмена сооб- щениями, тем самым избавляясь от части сложной функциональности. • Платформенная/языковая интеграция. Зачастую удаленные системы создаются с использованием различных платформ, технологий и языков программирования. Интеграция разнородных систем требует использования связующего ПО, в каче- стве которого может выступить система обмена сообщениями. Идея использова- ния системы обмена сообщениями в качестве универсального связующего звена между приложениями была положена в основу шаблона шина сообщений {Message Bus, с. 162). • Асинхронное взаимодействие. Обмен сообщениями позволяет наладить взаимодей- ствие между приложениями по принципу отправил и забыл (send-and-fotgef). В со- ответствии с этим принципом отправитель не обязан ожидать подтверждение о получении и обработке сообщения от принимающей стороны; более того, он также не обязан ожидать подтверждение о доставке сообщения от системы обмена сообщениями. Единственное, о чем следует позаботиться отправителю, — это до- ждаться подтверждения об отправке сообщения, т.е. о его помещении в канал. Как только сообщение будет передано системе обмена сообщениями, отправитель может приступить к выполнению имеющихся у него задач. • Рассогласование во времени. При синхронном взаимодействии отправитель должен дождаться завершения обработки вызова получателем прежде, чем сделать новый вызов. Таким образом, скорость размещения вызовов отправителем ограничена скоростью их обработки получателем. Асинхронное взаимодействие позволяет размещать и обрабатывать вызовы с разной скоростью, что существенно повышает эффективность взаимодействия между приложениями. • Регулирование нагрузки. Слишком большое число удаленных вызовов процедур за короткий промежуток времени может привести к перегрузке получателя, сниже- нию его производительности и даже выходу из строя. Система обмена сообщения- ми формирует очередь запросов, позволяя получателю контролировать скорость их обработки. Поскольку взаимодействие осуществляется в асинхронном режиме, ретулирование нагрузки на стороне получателя не оказывает негативного влияния на отправителя. • Надежное взаимодействие. В отличие от удаленного вызова процедуры, обмен со- общениями позволяет наладить надежное взаимодействие между приложениями за счет подхода, получившего название передача с промежуточным хранением {store- and-forward). Как упоминалось выше, сообщение представляет собой единицу пе- редачи информации, инкапсулирующую полезные данные. Когда отправитель по-
Введение 29 мещает сообщение в канал, система обмена сообщениями сохраняет его на ком- пьютере отправителя. Затем сообщение доставляется получателю и сохраняется на его компьютере. Предположим, что сохранение сообщения на компьютерах от- правителя и получателя является надежной операцией. (Чтобы сделать ее еще на- дежнее, сообщение можно сохранять не в памяти, а на диске компьютера, как описывается шаблоном гарантированная доставка (Guaranteed Delivery, с. 149).) Единственным слабым звеном передачи с промежуточным хранением является доставка сообщения на компьютер получателя. Чтобы нивелировать негативное влияние возможных сбоев при передаче сообщения, система обмена сообщениями пересылает его до тех пор, пока оно не будет доставлено по назначению. Автома- тическая пересылка сообщения позволяет исключить риск потери информации при возникновении сбоя в сети или на компьютере получателя, что, в свою оче- редь, делает возможным применение принципа взаимодействия между приложе- ниями “отправил и забыл”. • Работа без подключения к сети. Некоторые приложения ориентированы на работу без подключения к сети. Как правило, подобные приложения предназначены для выполнения на ноутбуках или КПК и периодически (при наличии сетевого под- ключения) синхронизируют данные с сервером. Обмен сообщениями— идеаль- ное решение для синхронизации, позволяющее накапливать данные в очереди до тех пор, пока приложение не получит доступ к сети. • Посредничество. Система обмена сообщениями выступает в роли посредника (Mediator) [12] между взаимодействующими приложениями. Приложение может использовать систему обмена сообщениями в качестве каталога доступных для ин- теграции приложений и служб. Если приложение потеряет связь с другими прило- жениями. ему понадобится восстановить соединение только с системой обмена сообщениями, а не с каждым отдельным приложением. Функция посредника мо- жет потребовать от системы обмена сообщениями высокой доступности, баланси- ровки нагрузки, устойчивости к отказам сетевых соединений, а также поддержки качества обслуживания. • Управление потоками. Асинхронное взаимодействие позволяет приложению не ожидать результата выполнения задачи другим приложением. Вместо этого приложение может воспользоваться обратным вызовом, уведомляющим его о по- ступлении ответа (шаблон запрос-ответ — Request-Reply, с. 177). Большое число заблокированных потоков, а также потоки, заблокированные в течение длитель- ного времени, могут оказать негативное воздействие на работу приложения. Кро- ме того, такие потоки трудно восстановить в случае сбоя приложения и его после- дующего перезапуска. Использование обратного вызова позволяет минимизиро- вать количество заблокированных потоков, обеспечить стабильную работу приложения и определить потоки, которые должны быть восстановлены при его перезапуске. Итак, существует несколько причин, свидетельствующих в пользу обмена сообще- ниями. Некоторые из них носят сугубо технический характер, в то время как остальные представляют собой стратегические решения, принимающиеся на этапе проектирования приложения. Безусловно, каждое из вышеперечисленных преимуществ обмена сообше-
30 Введение ниями будет иметь различный вес в контексте конкретных требований, предъявляемых к приложению. Однако мы уверены, что каждое из них является достаточным аргумен- том для использования технологии обмена сообщениями при интеграции приложений. Недостатки асинхронного обмена сообщениями Несмотря на то что технология асинхронного обмена сообщениями позволяет пре- одолеть множество трудностей, связанных с интеграцией разнородных приложений, она не лишена недостатков. Некоторые из них являются неотъемлемой частью асинхронной модели взаимодействия, в то время как остальные зависят от конкретной реализации системы обмена сообщениями. • Сложная модель программирования. Асинхронный обмен сообщениями требует от разработчиков использования модели событийно управляемого программирования. В этом случае логика приложения разбивается на множество обработчиков событий, реагирующих на входящие сообщения. Подобную систему гораздо труднее програм- мировать и отлаживать, чем систему, основанную на вызове методов. Так, эквива- лентом простого вызова метода в модели событийно управляемого программирова- ния является совокупность, состоящая из сообщения с запросом, канала запроса, сообщения с ответом, канала ответа, идентификатора корреляции и очереди сооб- щений недопустимого формата (см. шаблон запрос-ответ —Request-Reply, с. 177). • Порядок доставки сообщений. Система обмена сообщениями гарантирует доставку сообщения от отправителя к получателю, не оговаривая требующееся для этого время. В результате может быть нарушен порядок, в котором были отправлены со- общения. Если последовательность доставки сообщений имеет значение, ее нужно восстановить, как описано в шаблоне преобразователь порядка (Resequencer, с. 297). • Необходимость реализации синхронной модели. Не все приложения могут взаимо- действовать по принципу “отправил и забыл”. К примеру, пользовательский за- прос о наличии авиабилетов должен быть обработан немедленно, а не в течение неопределенного промежутка времени. Следовательно, в некоторых системах об- мена сообщениями должен быть предусмотрен баланс между синхронной и асин- хронной моделями взаимодействия. • Производительность. Системы обмена сообщениями вносят дополнительные из- держки в процесс взаимодействия между приложениями. На создание, отправку, получение и обработку сообщения уходят время и ресурсы. К тому же передача большого объема данных может повлечь за собой создание несметного числа со- общений. Так, зачастую интеграция двух существующих систем начинается с реп- ликации всех необходимых данных. Репликация большого объема информации с помощью средств ETL (Extract, Transform and Load— “извлечение, преобразова- ние, загрузка”) гораздо эффективнее репликации с помощью обмена сообщения- ми. Таким образом, обмен сообщениями рекомендуется применять для синхрони- зации данных между приложениями, а не для их первичной репликации. • Ограниченная поддержка программными платформами. Многие коммерческие сис- темы обмена сообщениями недоступны для всех платформ. Зачастую единствен- ный способ интеграции приложений заключается в использовании протокола
Введение 31 FTP, поскольку целевая программная платформа не поддерживается конкретной системой обмена сообщениями. • Зависимость от компании-разработчика. Коммерческие системы обмена сообще- ниями могут основываться на использовании закрытых протоколов. Даже такая общепринятая спецификация обмена сообщениями, как JMS, не определяет под- робностей реализации конкретного решения. В результате различные системы об- мена сообщениями оказываются неспособными к взаимодействию друг с другом. Это может привести к возникновению новой задачи интеграции: интеграции нескольких различных интеграционных решений! (См. шаблон мост обмена сооб- щениями Messaging Bridge, с. 159). Подведем итог. Технология асинхронного обмена сообщениями не решает всех задач интеграции. Более того, ее использование может привести к необходимости преодоления новых трудностей. Взвесьте все “за” и “против”, прежде чем приступить к реализации конкретного интеграционного решения с помощью обмена сообщениями. Мыслим асинхронно Обмен сообщениями— это технология асинхронного взаимодействия приложений с гарантией доставки данных. В то же время большинство приложений использует син- хронные вызовы функций; например, процедура вызывает подпроцедуру, один метод вы- зывает другой или же процедура вызывает другую процедуру через технологию удален- ного вызова (такую, как CORBA или DCOM). Синхронный вызов требует от вызываю- щего процесса ожидания завершения выполнения функции подпроцессом. Даже при использовании удаленного вызова, подразумевающего выполнение подпроцедуры в от- дельном процессе, вызывающий процесс приостанавливает свое выполнение до возврата управления (а также результата выполнения подпроцедуры). При использовании асин- хронного обмена сообщениями приложения могут взаимодействовать по принципу “отправил и забыл”, позволяющему вызывающему приложению разместить сообщение в канале и тотчас же вернуться к выполнению текущей задачи. Другими словами, вызы- вающая процедура продолжает свое выполнение во время вызова подпроцедуры, как по- казано на рис. 2. Рис. 2. Семантика синхронного и асинхронного вызовов
32 Введение Асинхронное взаимодействие имеет ряд отличительных особенностей. Во-первых, речь идет о более чем одном потоке выполнения. Наличие нескольких потоков позволяет подпроцедурам выполняться одновременно, что существенно увеличивает производи- тельность приложения, однако затрудняет его отладку. Во-вторых, результат выполнения подпроцедуры (если таковой имеется) возвращается посредством механизма обратного вызова. С одной стороны, это позволяет увеличить производительность, так как вызы- вающий процесс может заняться выполнением других задач, не дожидаясь возвращения результата. С другой стороны, вызывающий процесс должен быть готов к обработке ре- зультата в любой момент (даже во время выполнения другой задачи), а также помнить контекст, в котором был осуществлен вызов. В-третьих, асинхронные подпроцессы могут выполняться в любом порядке. Это накладывает на вызывающий процесс еще одно тре- бование: уметь обрабатывать полученные результаты с учетом их источника и времени получения. Таким образом, асинхронная модель взаимодействия имеет несколько неос- поримых преимуществ, однако требует от разработчика переосмыслить способ использо- вания процедурой своих подпроцедур. Распределенное приложение или интеграция приложений Зачастую корпоративные приложения распределяются между несколькими компью- терами за счет использования n-уровневой архитектуры (усовершенствованный вариант архитектуры клиент/сервер). Несмотря на то что процессы и-уровневого приложения выполняются на нескольких компьютерах и взаимодействуют между собой, интеграция приложений существенно отличается от распределенного приложения. Почему же использование n-уровневой архитектуры не позволяет говорить об инте- грации? Во-первых, взаимодействие между общающимися сторонами построено по принципу сильной связи — ни один из уровней приложения не может функционировать без оставшихся уровней. Во-вторых, взаимодействие между уровнями синхронно. В-третьих, пользователи приложения (одно- или многоуровневого) — это люди, которые привыкли к быстрому отклику системы. В то же время интеграция подразумевает налаживание взаимодействия между незави- сящими друг от друга приложениями по принципу слабой связи. Каждое из интегриро- ванных приложений выполняет определенный круг задач, обращаясь к другим приложе- ниям для получения некоторой дополнительной функциональности. Интегрированные приложения взаимодействуют асинхронно, что позволяет им продолжать работу, не до- жидаясь ответа от вызываемой стороны. Это же делает возможным отказ от жестких вре- менных ограничений, присущих пользовательским приложениям. Коммерческие системы обмена сообщениями Очевидные преимущества интеграционных решений, использующих асинхронный обмен сообщениями, дали толчок к созданию рынка соответствующего связующего ПО и средств разработки. Ниже перечислены четыре основные категории коммерческих про- дуктов, ориентированных на обмен сообщениями.
Введение 33 1. Операционные системы. Популярность технологии обмена сообщениями побуди- ла разработчиков программного обеспечения интегрировать необходимую ин- фраструктуру в операционные системы и СУБД. К примеру, корпорация Microsoft включила в состав операционных систем Windows 2000 и Windows ХР службу Microsoft Message Queuing (MSMQ). Служба MSMQ доступна посредством нескольких API, включая компоненты СОМ и классы пространства имен Microsoft .NET System.Messaging. Аналогичная функциональность (Oracle AQ) была реализована в СУБД Oracle. 2. Серверы приложений. Впервые компания Sun Microsystems включила специфи- кацию Java Messaging Service (JMS) в версию 1.2 платформы J2EE. С тех пор прак- тически все серверы приложений J2EE (такие, как IBM WebSphere и BEA WebLogic) включают в себя реализацию JMS. Кроме того, эталонная реализация JMS поставляется в составе J2EE JDK. 3. Решения для интеграции корпоративных приложений. Как правило, решения для интеграции корпоративных приложений обладают богатой функциональностью и включают в себя систему обмена сообщениями, средства автоматизации доку- ментооборота и деловых операций, средства создания порталов и др. Наиболее известными EAI-решениями являются IBM WebSphere MQ, Microsoft BizTalk, TIBCO, WebMethods, SeeBeyond, Vitria, CrossWorlds и др. Некоторые из этих про- дуктов содержат несколько различных API, обеспечивающих обмен сооб- щениями, в то время как остальные (например, SonicSoftware и Fiorano) ориенти- руются исключительно на JMS. 4. Средства создания Web-служб. Web-службы привлекли к себе огромный интерес со стороны разработчиков интеграционных решений. В настоящее время усилия комитетов и консорциумов по стандартизации сосредоточены на принятии специ- фикации технологии надежного обмена сообщениями на основе Web-служб (стандарты WS-Reliability. WS-ReliableMessaging и ebMS). В то же время на рынке появляется все больше и больше продуктов, реализующих маршрутизацию, преоб- разование и управление решениями, основанными на использовании Web-служб. Шаблоны, представленные в этой книге, не ориентированы на конкретного постав- щика ПО и применимы к большинству интеграционных решений, основанных на обме- не сообщениями. К сожалению, практически все существующие на рынке системы об- мена сообщениями используют собственную терминологию. Мы же постарались подоб- рать простые, описательные имена шаблонов, не зависящие от конкретной технологии или решения. Многие поставщики интеграционных решений, основанных на обмене сообщения- ми, реализовали некоторые из представленных в этой книге шаблонов в своих продуктах. Читатели, знакомые с терминологией конкретного поставщика, не должны испытывать трудностей при освоении языка шаблонов. В этом им помогут следующие таблицы.
34 Введение Терминология коммерческих систем обмена сообщениями Шаблоны интеграции корпоративных приложений Java Message Service (JMS) Microsoft MSMQ WebSphere MQ Канал сообщений (Message Channel, с. 93) Destination MessageQueue Queue Канал “точка-точка” (Point-to- Point Channel, с. 131) Queue MessageQueue Queue Канал “публикация-подписка” (Publish-Subscribe Channel, с. 134) Topic — — Сообщение (Message, с. 98) Message Message Message Конечная точка сообщения (Message Endpoint, с. 124) MessageProducer, MessageConsumer — — Терминология коммерческих систем обмена сообщениями Шаблоны интеграции корпоративных приложений TIBCO WebMethods SeeBeyond Vitria Канал сообщений (Message Channel, с. 93) Subject Queue Intelligent Queue Channel Канал “точка-точка” (Point-to- Point Channel, с. 131) Distributed Queue Deliver Action Intelligent Queue Channel Канал “публикация-подписка” (Publish-Subscribe Channel, с. 134) Subject Publish- Subscribe Action Intelligent Queue Publish-Subscribe Channel Сообщение (Message, с. 98) Message Document Event Event Конечная точка сообщения Publisher, Publisher, Publisher, Publisher, (Message Endpoint, с. 124) Subscriber Subscriber Subscriber Subscriber Форма шаблонов Идея использования шаблонов для документирования приемов программирования была популяризирована благодаря таким книгам, как Design Patterns, Pattern Oriented Software Architecture, Core J2EE Patterns и Patterns of Enterprise Application Architecture (Фаулер M. Архитектура корпоративных программных приложений.— М.: Издательский дом “Вильямс”, 2004). Впервые концепция шаблонов и языка шаблонов была представ- лена в книгах Кристофера Александера (Christopher Alexander) A Pattern Language и A Timeless Way of Building. Каждый шаблон представляет собой некоторое решение, которое должно быть принято на этапе проектирования, а также его обоснование. Язык шаблонов— это набор тесно связанных между собой шаблонов. Применение шаблонов проектирования является одним из наиболее эффективных способов документирования экспертных знаний.
Введение 35 Язык шаблонов позволяет решать неограниченное число задач в рамках конкретной проблемной области. Как правило, каждая решаемая задача предполагает уникальный выбор и способ использования шаблонов. Эта книга поможет вам найти верный ответ на любой вопрос, связанный с применением технологии обмена сообщениями. Использование формы шаблонов не гарантирует успех книги. Недостаточно сказать: “Для решения этой задачи примените такой-то шаблон’’. Шаблон представляет ценность только в том случае, если он содержит обоснование сложности задачи, описание возмож- ных способов ее решения и объяснение преимуществ предлагаемого подхода. Кроме того, шаблоны должны быть связаны друг с другом для наглядной иллюстрации взаимо- проникновения проблем проектирования. В этом случае форма шаблонов не только под- скажет способ решения конкретной задачи, но и поможет выработать подход к успеш- ному преодолению новых, не предусмотренных авторами этой книги, проблем. В некотором смысле шаблоны подобны директивам. Они не описывают проблему или ее решение — вместо этого шаблоны учат решать проблему. Каждый шаблон представ- ляет собой вопрос, ответ на который необходимо дать разработчику, например “Стоит ли использовать обмен сообщениями?” или “Будет ли оправдана в данной ситуации отправка сообщения с командой?". Суть шаблонов и языка шаблонов заключается в способствова- нии принятию правильных решений в любой (даже не предусмотренной автором шабло- на) ситуации. Универсальной формы шаблона не существует. Избранный нами стиль очень близок к форме Александера, ставшей популярной благодаря книге Кента Бека (Kent Beck) Smalltalk Best Practice Patterns. Для улучшения восприятия материала мы использовали такие элементы стилевого оформления, как подчеркивание, курсив, а также наглядные иллюстрации. Форма каждого шаблона, представленного в этой книге, состоит из следующих элементов. • Имя. Имя шаблона отражает его назначение. Основным критерием, использован- ным при выборе имени шаблона, была простота употребления этого имени в пред- ложениях. а значит, и в разговорах между проектировщиками. • Пиктограмма. В добавок к имени большинство шаблонов имеет пиктограмму. Необходимость использования пиктограмм была обусловлена тем, что многие архитекторы привыкли работать с диаграммами, т.е. с визуальным представлением шаблонов. К тому же применение пиктограмм позволяет наглядно представить композицию нескольких шаблонов. • Контекст. В этом разделе описывается ситуация, которая привела к возникнове- нию задачи. Зачастую в контексте упоминаются другие шаблоны проектирования. • Задача. Постановка задачи представлена в виде вопросительного предложения, ог- раниченного двумя горизонтальными линиями. • Оценка сложности. В этом разделе описываются ограничения, затрудняющие ре- шение задачи. Также здесь могут упоминаться альтернативные решения, приме- нение которых по тем или иным причинам нецелесообразно. • Решение. Описание действий, которые необходимо предпринять для решения задачи. Постановка задачи и ее решение являются ключевыми компонентами шаблона. Чтобы облегчить повторное использование книги, для выделения текста постановки и решения задачи используется одинаковое стилевое оформление.
36 Введение • Эскиз. Одной из наиболее привлекательных особенностей формы Александера является наличие эскиза, иллюстрирующего решение задачи. В большинстве слу- чаев для понимания сути шаблона достаточно взглянуть на его имя и эскиз реше- ния. Последовав примеру, мы разместили эскиз решения непосредственно после его описания для каждого шаблона. • Результат. В этой части рассматриваются особенности применения решения, а также трудности, которые могут при этом возникнуть • Что дальше. В этом разделе перечисляются шаблоны, на которые стоит обратить внимание после применения решения. Как правило, использование одного из шаблонов ведет к возникновению новых трудностей, для устранения которых сле- дует обратиться к другим шаблонам. Высокая степень взаимопроникновения шаб- лонов — одна из основных особенностей, отличающих язык шаблонов от простого каталога шаблонов. • Врезки. Врезки содержат информацию о технических подробностях или разновид- ностях шаблона. Специфическое стилевое форматирование позволяет пропустить врезку, если она не касается интересующей вас реализации шаблона. • Примеры. Обычно шаблон содержит один или несколько примеров его примене- ния на практике. Пример реализации шаблона может содержать как одно лишь упоминание об известном способе его использования, так и большой сегмент программного кода. Учитывая разнообразие существующих технологий обмена сообщениями, мы не рассчитываем на то, что читатель будет знаком с каждой из них. Именно поэтому мы используем форму шаблона, позволяющую безболез- ненно пропустить примеры, не потеряв при этом важной информации. Самое большое преимущество использования шаблонов состоит в том, что, помимо решения конкретной задачи, шаблон позволяет разрабатывать решения для новых, не предусмотренных его авторами задач. Таким образом, представленные в книге шабло- ны могут быть использованы при работе не только с существующими системами обмена сообщениями, но и с системами обмена сообщениями, которые будут созданы после ее выхода в свет. Диаграммы, использованные в книге Интеграционные решения состоят из множества различных компонентов— прило- жений, баз данных, конечных точек, каналов, сообщений, маршрутизаторов и т.д. Чтобы описать интеграционное решение, следует определить нотацию, содержащую средства для представления вышеперечисленных компонентов. К сожалению, на сегодняшний день не существует всеобъемлющей, широко известной нотации, с помощью которой можно было бы описать все аспекты интеграционных решений. Унифицированный язык моделирования (Unified Modeling Language— UML) отлично подходит для описания объектно-ориентированных систем с помощью диаграмм классов и взаимодействия, од- нако он не содержит семантику для описания решений, основанных на обмене сообще- ниями. Профиль UML для интеграции корпоративных приложений (UML Profile for EAI — UMLEAI) [42] расширяет семантику диаграмм взаимодействия за счет поддержки
Введение 37 описания обмена сообщениями между компонентами системы. Эта нотация может слу- жить отличной наглядной спецификацией для генерации кода как часть архитектуры, управляемой моделью (model-driven architecture— MDA). Тем не менее мы приняли решение отказаться от профиля UMLEA1 по двум причинам. Во-первых, с помощью UMLEAI нельзя описать все шаблоны, представленные в этой книге. Во-вторых, нашей целью является не точная визуальная спецификация, а “эскиз” или “набросок”, способ- ный максимально просто и лаконично передать суть шаблона. Именно поэтому мы и ре- шили разработать собственную “нотацию”, не требующую от читателя изучать длинную документацию по ее использованию. Пример употребления созданной нами нотации представлен на рис. 3. На рис. 3 изображено сообщение, передаваемое по каналу компоненту в самом широ- ком смысле этого слова. Так, это может быть интегрируемое приложение; посредник, преобразующий сообщения или маршрутизирующий их между приложениями; опреде- ленная часть приложения. Если на рисунке необходимо подчеркнуть использование канала, он изображается в виде трехмерной трубки. Однако гораздо чаще акцент перено- сится на компоненты, а канал изображается в виде линии с указывающей стрелкой. Два различных способа представления канала на рисунке полностью эквивалентны. Как показано на рис. 3, сообщению соответствует небольшое дерево с круглым корнем и квадратными вложенными элементами. Подобный способ представления сообщения обусловливается использованием многими системами обмена сообщениями древовид- ных структур данных, таких как документы XML. Элементы дерева могут быть заштрихо- ваны или залиты определенным цветом для подчеркивания способа их использования в конкретном шаблоне. В частности, это позволяет создать наглядное визуальное пред- ставление для шаблонов преобразования, предназначенных для добавления, изменения порядка следования или удаления полей сообщения. Сообщение Канал Компонент Рис. 3. Пример визуального представления компонентов интеграционного решения Описывая структуру приложения, мы не используем стандартные диаграммы классов и циклограммы UML для представления иерархии классов и взаимодействия между объектами. Одним из наиболее авторитетных источников информации по нотации UML является [41].
38 Введение Примеры и практикумы Стараясь подчеркнуть широкую применимость шаблонов проектирования, представ- ленных в этой книге, мы включили в нее множество примеров использования различных технологий интеграции. Недостаток подобного подхода состоит в том, что читатель мо- жет не быть знаком с каждой из упомянутых нами технологий. Именно поэтому мы по- старались сделать все примеры исключительно факультативными—в них не содержится важной информации, касающейся шаблона. Там, где это было возможно, мы приводили несколько примеров реализации с использованием различных технологий интеграции. Включая в текст программный код, мы прежде всего заботились о его удобочитаемо- сти, а не о возможности выполнения. Фрагмент кода способен снять все вопросы, касаю- щиеся шаблона. Именно поэтому многие разработчики и архитекторы предпочитают просмотреть несколько десятков строк кода, а не длинные параграфы текста. Чтобы об- легчить восприятие кода, мы приводили только наиболее важные методы и классы реше- ния, а также избегали большинства форм проверки ошибок. Практически все фрагменты кода не содержат комментариев, поскольку код обсуждается в прилегаюших к нему абза- цах текста. Приведение полноценного примера использования шаблона интеграционного реше- ния весьма затруднительно. Как правило, подобные решения состоят из множества гете- рогенных компонентов, распределенных между различными системами. К тому же большинство интеграционных шаблонов тесно связаны с другими шаблонами. Чтобы продемонстрировать взаимозависимость нескольких шаблонов, мы включили в книгу несколько сложных примеров в виде так называемых “практикумов” (главы 6, 9 и 12). Рассмотренные нами примеры иллюстрируют многие проблемы проектирования слож- ных решений, основанных на обмене сообщениями. Хотим подчеркнуть, что все примеры, приведенные в книге, носят иллюстративный характер и не могут применяться в качестве отправной точки при создании интеграцион- ного решения, пригодного для применения в реальных условиях. В частности, практиче- ски во всех примерах отсутствует проверка ошибок, а также средства обеспечения надеж- ности, безопасности и масштабируемости. При наличии такой возможности мы старались использовать в примерах бесплатные программные платформы или же платформы, для которых имеется общедоступная проб- ная версия. Иногда мы применяли коммерческие платформы (такие, как TIBCO ActiveEnterprise и Microsoft BizTalk) с целью продемонстрировать различие между ис- пользованием платных программ и разработкой решения “с нуля”. В подобных случаях мы старались сделать так, чтобы читатель извлек пользу из примера, даже не имея под рукой необходимых программных средств. Большинство примеров основано на исполь- зовании таких инфраструктур для обмена сообщениями, как JMS и MSMQ. Это позволя- ет в полной мере сфокусироваться на существующих проблемах реализации интеграци- онных решений вместо того, чтобы пытаться избежать их с помощью более функцио- нального связующего ПО. Все Java-примеры, приведенные в этой книге, основаны на спецификации JMS 1.1, включенной в версию 1.4 платформы J2EE. Ко времени опубликования книги большин- ство серверов обмена сообщениями и серверов приложений будут поддерживать JMS 1.1.
Введение 39 Эталонную реализацию JMS можно загрузить с Web-сайта компании Sun Microsystems по адресу http://java.sun.com/j 2ee. Также в книге приводятся примеры, основанные на версии 1.1 платформы Microsoft .NET и написанные на языке программирования С#. Набор инструментальных средств разработки для платформы .NET Framework можно загрузить с Web-сайта корпорации Microsoft по адресу http: //msdn. microsof t. com/net. Как организована эта книга Язык шаблонов, представленный в этой книге, представляет собой множество взаи- мосвязанных шаблонов проектирования. В то же время в языке шаблонов можно выде- лить несколько ключевых элементов (так называемых корневых шаблонов), формирующих его логическую структуру. При группировании шаблонов по главам этой книги учитывался их уровень абстрак- ции, а также область применения (рис. 4). Основным шаблоном проектирования книги является шаблон обмен сообщениями (Messaging, с. 87). К корневым шаблонам относятся шаблоны канал сообщений (Message Channel, с. 93), сообщение (Message, с. 98), каналы и фильтры (Pipes and Filters, с. 102), мар- шрутизатор сообщений (Message Router, с. 109), транслятор сообщений (Message Translator, с. 115) и конечная точка сообщения (Message Endpoint, с. 124). Каждый из корневых шаб- лонов рассматривается в отдельной главе. Исключение составляет шаблон каналы и фильтры, рассматриваемая в нем концепция не имеет прямого отношения к обмену со- общениями, а формирует основу для шаблонов маршрутизации и преобразования. Рис. 4. Корневые шаблоны проектирования Описанная выше иерархия шаблонов проектирования рассматривается в следующих главах. • Глава 2. В этой главе рассматриваются различные подходы к интеграции прило- жений, включая обмен сообщениями. • Глава 3. В этой главе рассматриваются шесть фундаментальных шаблонов проек- тирования, представленных в книге.
40 Введение • Глава 4. Приложения взаимодействуют между собой посредством каналов. Каналы определяют логические маршруты, по которым могут передаваться сообщения. Эта глава посвящена выбору каналов обмена сообщениями для конкретного при- ложения. • Глава 5. В этой главе рассматриваются различные форматы сообщений и их свой- ства. • Глава 7. Решения, основанные на обмене сообщениями, предполагают разделение отправителя и получателя информации. Отправитель пересылает сообщение мар- шрутизатору, который обеспечивает его доставку получателю. В этой главе рас- сматриваются различные способы создания маршрутизаторов сообщений. • Глава 8. Зачастую независимо созданные приложения используют различные форматы сообщений, кодировку символов и т.п. В этой главе рассматривается создание промежуточных компонентов, преобразующих формат отправителя в формат получателя сообщения. • Глава 10. Многие приложения изначально не приспособлены для участия в систе- мах обмена сообщениями. В этой главе рассматривается уровень, обеспечиваю- щий отправку и получение сообщений, который тем самым превращает приложе- ние в конечную точку системы обмена сообщениями. • Глава 11. Эта глава посвящена тестированию и мониторингу системы обмена со- общениями. Представленные выше главы содержат всю необходимую информацию, касающуюся интеграции приложений с использованием обмена сообщениями. С чего начать Приступая к работе с книгой, охватывающей обширную область знаний, важно опре- делить наиболее эффективный способ ее прочтения. Несмотря на то что метод чтения “от корки до корки” гарантирует изучение всего материала, представленного в настоя- щей книге, это далеко не самый быстрый способ добраться до нужной темы. Начинать чтение книги с произвольного шаблона — также не самая удачная идея: в этом случае вы рискуете упустить важную информацию, необходимую для понимания шаблона. К счастью, представленный в книге язык шаблонов построен вокруг упоминавшихся выше корневых шаблонов. Все вместе корневые шаблоны позволяют получить наглядное представление о языке шаблонов, а по отдельности представляют собой прекрасные от- правные точки для более глубокого изучения технологий обмена сообщениями. Описа- ние всех корневых шаблонов содержится в главе 3. В главе 2 рассматриваются основные подходы к интеграции приложений, включая обмен сообщениями (Messaging, с. 87). Прочитайте эту главу, если вы впервые столкнулись с про- блемой интеграции приложений и хотите узнать о преимуществах и недостатках сущест- вующих интеграционных технологий. В противном случае вы можете пропустить главу 2. Глава 3 содержит описание всех корневых шаблонов, за исключением шаблона обмен сообщениями, который рассматривается в главе 2. Прочитайте (или хотя бы просмотрите) главу 3, чтобы получить общее представление об используемом в книге языке шаблонов. Для более глубокого изучения той или иной темы ознакомьтесь с соответствующим кор-
Введение 41 левым шаблоном, после чего переходите к рассмотрению шаблонов, перечисленных в описании этого корневого шаблона. Начиная с главы 4, различным участникам процесса интеграции приложений пред- лагается обратить внимание на следующий материал. • Системным администраторам рекомендуется обратить внимание на тему выбора каналов обмена сообщениями (глава 4) и обслуживания системы обмена сообще- ниями (глава 11). • Разработчики приложений должны ознакомиться с вопросом интеграции прило- жения с системой обмена сообщениями (глава 10) и выбора формата отправляе- мых сообщений (глава 5). • Системные интеграторы извлекут максимум пользы из чтения главы 7, посвящен- ной доставке сообщений в конечные точки, и главы 8, описывающей преобразо- вание формата отправителя в формат получателя сообщения. Если вам нужно найти шаблон, подходящий для применения в конкретной ситуации, обращайте внимание только на постановку задачи и ее решение. Этой информации будет вполне достаточно, чтобы понять, интересует вас данный шаблон или нет. Обратите внимание, что порядок следования шаблонов в книге не определяет реко- мендуемый порядок их изучения. Столкнувшись с той или иной задачей интеграции, вы- берите соответствующий ей корневой шаблон. Из его контекста вы узнаете, какие шаб- лоны следует применить перед использованием данного корневого шаблона (их описа- ния могут располагаться как до, так и после описания корневого шаблона), а из раздела, предшествующего примерам, — какие шаблоны следует применить после использования данного корневого шаблона (опять-таки, описания этих шаблонов необязательно будут следовать после описания корневого шаблона). Другими словами, эта книга представляет собой “паутину” взаимосвязанных шаблонов, а не их последовательное описание. Поддержка Дополнительные материалы к книге, а также информация, касающаяся интеграции корпоративных приложений, доступна в Интернете на Web-сайте www. enterprisein- tegrationpatterns. com. Комментарии, пожелания и отзывы присылайте по адресу authors@enterpriseintegrationpatterns.com. Резюме Назначение этого введения — ознакомить читателей со следующими фактами и фун- даментальными концепциями: • что такое обмен сообщениями; • что такое система обмена сообщениями; • преимущества технологии обмена сообщениями; • отличия асинхронного и синхронного программирования;
42 Введение • отличия интеграции приложений от создания распределенного приложения; • существующие категории коммерческих программных продуктов, поддерживаю- щих обмен сообщениями. Кроме того, во введении рассматривалась организация книги и способ подачи мате- риала. В частности, особое внимание было уделено: • роли шаблонов в структурировании материала книги; • нотации, использующейся для описания интеграционных решений; • назначению и области применения приведенных в книге примеров; • организации материала; • определению наиболее эффективного способа изучения материала. Ознакомившись с базовыми понятиями и способом организации материала, присту- пим к изучению интеграции корпоративных приложений с использованием обмена сообщениями.
Глава 1 Решение задач интеграции с помощью шаблонов проектирования В этой главе рассматривается применение шаблонов проектирования для решения типичной интеграционной задачи. В общей сложности мы познакомимся более чем с двумя десятками наиболее распространенных шаблонов интеграции. Необходимость интеграции Типичная информационная система предприятия насчитывает сотни, если не тыся- чи, приложений (коммерческих, собственной разработки, унаследованных и т.д.), вы- полняющихся под управлением различных операционных систем. Тридцать Web-сайтов, три экземпляра SAP и множество решений уровня подразделения— вполне обыденная ситуация для крупной компании. Возникает вопрос: “Как владельцы предприятий допускают такой хаос?”. На первый взгляд, любой IT-директор, ответственный за подобное “спагетти” из приложений, должен быть немедленно уволен. На практике, однако же, дело обстоит несколько по-иному. Во-первых, разработка бизнес-приложений— невероятно сложная задача. Создание единственного приложения, охватывающего все бизнес-функпии предприятия, практи- чески невозможно. Наибольшего успеха в создании тяжеловесных бизнес-приложений достигли разработчики ERP-систем. Однако даже такие гиганты индустрии, как SAP, Oracle, PeopleSoft и др., вынуждены сконцентрировать свои усилия лишь на части бизнес- задач типичной компании. Об этом, в частности, красноречиво свидетельствует тот факт, что на сегодняшний день ERP-системы являются одними из наиболее популярных точек интеграции. Во-вторых, распределение бизнес-функций между несколькими приложениями пре- доставляет компаниям возможность выбора “лучшего” пакета программ для бухгалтер- ского учета, “лучшего” приложения для управления взаимоотношениями с клиентами, “лучшей” системы обработки заказов и др. Учитывая многообразие индивидуальных бизнес-требований предприятий, создание универсального бизнес-приложения не вхо- дит в интересы разработчиков ПО.
44 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Современные бизнес-приложения создаются для решения определенной задачи. Темне менее нескончаемый поток требований к расширению функциональности со временем приводит к появлению в программном пакете дополнительных функций. К примеру, многие биллинговые системы обзавелись базовыми возможностями обслу- живания клиентов и ведения учета. С другой стороны, некоторые разработчики ПО для обслуживания заказчиков начали встраивать в свои приложения определенные функции биллинга, такие как прием и удовлетворение заявлений. Определить четкие границы ме- жду системой обслуживания заказчиков и биллинговой системой в этом случае достаточ- но трудно. Например, к какой из двух систем следует отнести функцию удовлетворения заявления клиента относительно выставленного ему счета? Взаимодействуя с компанией, пользователи (клиенты, бизнес-паргнеры и сотрудники компании), как правило, не задумываются о том, каким образом осуществляется это взаимодействие. В то же время выполнение каждой бизнес-функции может затрагивать сразу несколько внутренних систем компании. К примеру, клиент хочет изменить ин- формацию о своем адресе, а также проверить, был ли получен его последний платеж. В большинстве компаний обработка подобного запроса возлагается на две системы: обслуживания клиентов и биллинга. Подобным образом размещение клиентом нового заказа требует координации целого ряда различных систем. Компания должна проверить идентификатор клиента, убедиться в его положительной кредитной репутации, прове- рить доступность необходимого товара на складе, выполнить заказ, посчитать стоимость доставки, сформировать и отправить счет и т.д. Таким образом, размещение нового зака- за затрагивает как минимум 5-6 различных систем компании. С точки зрения клиента, размещение заказа—это всего лишь одна бизнес-транзакция. Для поддержания общих бизнес-процессов, а также совместного использования дан- ных несколькими приложениями последние необходимо интегрировать. Основной целью интеграции является обеспечение эффективного, надежного и безопасного обме- на данными между интегрируемыми приложениями. Трудности интеграции Интеграция корпоративных приложений — весьма непростое занятие. По определе- нию интеграция корпоративных приложений подразумевает обеспечение взаимодейст- вия между множеством программ, выполняющихся под управлением различных плат- форм и расположенных в различных местах предприятия. Таким образом, фраза простая интеграция является ни чем иным, как оксюмороном. Некоторые разработчики ПО предлагают пакеты для интеграции корпоративных приложений (Enterprise Application Integration — EAI), поддерживающие различные платформы, языки про- граммирования, а также наиболее популярные бизнес-приложения. К сожалению, тех- ническая инфраструктура большинства EAI-пакетов учитывает только часть трудностей, свойственных интеграции корпоративных приложений. Перечислим наиболее распро- страненные из них. • В большинстве случаев интеграция корпоративных приложений требует сущест- венного пересмотра корпоративной политики компании. Как правило, бизнес- приложения охватывают определенную проблемную область, такую как управле- ние взаимоотношениями с клиентами (Customer Relationship Management —
Трудности интеграции 45 CRM), биллинг или финансы. Как гласит известный закон Конвэя, “организации, проектирующие системы, неизбежно производят системы, являющиеся копиями их организационных структур”. Большинство организационных единиц в компа- нии создаются для решения конкретных задач. Налаживание взаимодействия ме- жду различными компьютерными системами приводит к необходимости установ- ки контактов и между использующими их подразделениями. В результате объединения большинства бизнес-функций компании деятельность последней становится зависимой от надлежащего функционирования интеграци- онного решения. Сбой в работе интеграционного решения может принести ком- пании миллионные убытки, связанные с потерей заказов, ошибочным направле- нием платежей и т.п. Одна из наиболее существенных проблем, связанных с созданием интеграционного решения, заключается в ограниченном контроле, который имеют разработчики ре- шения над интегрируемыми приложениями. В большинстве случаев объединяемые приложения представляют собой унаследованные системы или пакеты программ, внести изменения в которые не представляется возможным. Часто это приводит к тому, что на плечи создателей интеграционного решения ложится дополнительная задача по устранению недостатков в объединяемых приложениях и существующих между ними различий. Иногда часть интеграционного решения проще реализовать в конечных точках приложений, однако эта возможность может оказаться недоступ- ной по причинам политического или технического характера. Несмотря на растущий спрос на интеграционные решения, эта область разработки ПО пока еще не может похвастаться наличием большого числа общепринятых стан- дартов. Существенный толчок по направлению к стандартизации интеграционных решений дало появление таких технологий, как XML, XSL и Web-службы. К сожале- нию, слишком активное продвижение на рынок последних привело к появлению множества “расширений” и “интерпретаций”, также претендующих на звание стан- дартов. Будет уместным напомнить, что именно недостаток совместимости между различными “соответствующими стандарту” продуктами стал камнем преткновения для распространения такой интеграционной технологии, как CORBA. Существующие стандарты Web-служб XML позволяют преодолеть лишь часть трудностей интеграции корпоративных приложений. Утверждение, что XML — это “лингва-франка” системной интеграции, является, мягко говоря, неверным. Осуществление обмена данными в формате XML уместно сравнить с написанием текста с использованием только одного романского алфавита. Как известно, романский алфавит можно применять для представления многих языков и диалек- тов, неизвестных широкому кругу читателей. То же самое справедливо и для ин- теграции корпоративных приложений. Из существования единого представления данных (XML) не следует наличие общей семантики. К примеру, такое простое понятие, как “счет”, может иметь несколько различных семантик, подтекстов, ог- раничений и допущений в каждой конкретной системе. Устранение семантиче- ских различий между объединяемыми системами является одной из наиболее сложных и трудоемких задач интеграции.
46 Глава 1. Решение задач интеграции с помощью шаблонов проектирования • Поддержка существующего EAI-решения ничуть не проще, а то и сложнее его разра- ботки. Развертывание, мониторинг и устранение неполадок в интеграционном ре- шении требуют наличия у обслуживающего персонала целого ряда навыков. В боль- шинстве случаев полный набор требуемых навыков удается получить за счет привле- чения к обслуживанию EAI-решения множества различных служащих компании. Интеграционные решения являются важнейшим компонентом стратегии развития современных компаний. К сожалению, они способны значительно усложнить жизнь IT-персонала вследствие наличия существенных различий между высокоуровневым представлением EAI-решения (определяемым такими терминами, как “сквозная обра- ботка”, “Т+1”, “гибкая организация” и т.п.) и его низкоуровневой реализацией (какие параметры может принимать конструктор класса System.Messaging.XmlMessage- Formatter?). Роль интеграционных шаблонов проектирования Интеграции корпоративных приложений не свойственны простые решения. Тот, кто утверждает обратное, должен быть невероятно умным (по крайней мере, умнее авторов этой книги), полностью несведущим (скажем так, слишком “оптимистичным”) или фи- нансово заинтересованным в том, чтобы убедить вас поверить в простоту интеграции. Несмотря на то что интеграция приложений представляет собой обширную и слож- ную для изучения тему, всегда найдутся люди, разбирающиеся в ней на порядок лучше остальных. Каким секретным знанием они обладают? Что позволяет им с легкостью на- ходить ответы на всевозможные вопросы интеграции? Дело в том, что эти люди научи- лись обобщать накопленный ранее опыт в виде так называемых “шаблонов” и применять их при решении новых интеграционных задач. В отличие от готовых программных компонентов или фрагментов кода, шаблоны представляют собой ценные советы, описывающие решение той или иной проблемы. На практике интеграционные шаблоны проектирования способны заполнить простран- ство между высокоуровневым представлением задачи интеграции и ее фактической реализацией. Типы интеграционных задач Мы намеренно дали термину интеграция очень широкое определение. Для нас инте- грация означает объединение компьютерных систем, компаний или людей. Несмотря на то что данное определение позволяет нам включить в эту книгу огромный объем мате- риала, мы остановимся на шести наиболее распространенных типах интеграции: • информационные порталы; • репликация данных; • бизнес-функции совместного использования; • архитектуры, ориентированные на службы; • распределенные бизнес-процессы; • В2В-интеграция.
Типы интеграционных задач 47 Конечно же, приведенный выше список ни в коем случае не претендует на звание ис- черпывающей классификации задач интеграции. Тем не менее он дает наглядное пред- ставление о проектах, над которыми работают архитекторы интеграционных решений. Некоторые интеграционные задачи объединяют в себе сразу несколько типов интегра- ции. К примеру, создание распределенного бизнес-процесса зачастую требует проведе- ния начальной репликации данных между объединяемыми приложениями. Зачастую выполнение единственной бизнес-функции охватывает сразу несколько различных систем компании. К примеру, с целью проверки состояния заказа сотруднику может потребоваться доступ к системе управления заказами, расположенной на мэйн- фрейме, а также к системе обработки заказов, принятых посредством Web. Основная функция информационных порталов (рис. 1.1) заключается в обеспечении представле- ния информации из нескольких источников. В самых простых информационных порта- лах экран разделяется на несколько зон, каждая из которых соответствует той или иной системе. Более сложные порталы поддерживают ограниченное взаимодействие между зонами, например выбор пользователем элемента списка в зоне А приводит к отображе- нию подробной информации об этом элементе в зоне Б. Самые сложные информацион- ные порталы за счет высокого уровня функциональности практически стирают грань между порталом и интегрированным приложением. Рис. 1.1. Информационный портал Многие бизнес-системы нуждаются в доступе к одним и тем же данным. Например, такая информация, как адрес проживания клиента, может использоваться системой об- служивания заказчиков (при изменении адреса клиента), системой бухгалтерского учета (при подсчете налога с продаж), системой доставки товаров (при создании этикетки с ад- ресом доставки), а также биллинговой системой (при формировании счета). Некоторые из этих систем могут иметь собственное хранилище данных. При изменении адреса кли- ента каждая система должна получить копию обновленной информации. Этого можно добиться с помощью такого типа интеграции, как репликация данных (рис. 1.2). Существует множество различных способов реализации репликации данных. Функ- ция репликации может быть встроена в СУБД; нужные сведения можно экспортировать в файл для последующего импорта в другой системе, а также переслать внутри сообще- ний с помощью соответствующего связующего ПО.
48 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Рис. 1.2. Репликация данных Во многих бизнес-приложениях реализована избыточная функциональность. Так, сразу нескольким системам может понадобиться проверить номер социального страхова- ния, правильность указания почтового индекса в адресе проживания или же наличие определенного товара на складе. Каждую из этих функций можно вынести за пределы приложений и реализовать в виде функций совместного использования, доступных всем системам в виде служб (рис. 1.3). Рис. 1.3. Бизнес-функция совместного использования Совместно используемая бизнес-функция и репликация данных могут преследовать схожие цели. К примеру, копирование адреса проживания клиента во все требуемые системы можно заменить созданием совместно используемой бизнес-функции GetCus- tomerAddress. Выбор между двумя различными типами интеграции основывается на многочисленных критериях, таких как степень контроля над интегрируемыми системами (в отличие от помещения информации в базу данных, вызов совместно используемой функции предполагает более глубокое вмешательство в систему) и частота изменения данных (доступ к адресу проживания клиента осуществляется часто, а вот вероятность изменения последнего невысока). Совместно используемые бизнес-функции часто называют службами. Служба— это строго определенная и универсально доступная функция, реагирующая на запросы своих “потребителей”. Управление службами является одной из наиболее важных задач компа- нии. Во-первых, интегрируемым приложениям необходимо предоставить доступ к центра- лизованному списку всех доступных служб (так называемому каталогу служб). Во-вторых, описание интерфейса каждой службы должно способствовать согласованию контракта
Типы интеграционных задач 49 взаимодействия приложения с этой службой. Обнаружение службы и согласование кон- тракта взаимодействия с ней—две важнейшие составляющие SOA-архитектуры (рис. 1.4). SOA-архитектура стирает грань между интеграцией приложений и созданием распре- деленного приложения. К примеру, при создании нового приложения разработчики мо- гут полагаться на службы, предоставляемые другими приложениями. В этом случае об- ращение к службе может быть расценено как интеграция приложений. Однако во многих SOA-архитектурах вызов внешней службы практически ничем не отличается от вызова локального метода (за исключением производительности). Таким образом, разработку нового приложения в рамках существующей SOA-архитектуры можно сравнить с созда- нием распределенного приложения. Рис. 1.4. Архитектура, ориентированная на службы Одним из ключевых признаков того, что приложения необходимо интегрировать, является участие нескольких различных систем компании в выполнении единственной бизнес-транзакции (например, размещения заказа клиентом). В большинстве случаев вся функциональность, необходимая для выполнения бизнес-транзакйии, сконцентрирова- на в существующих приложениях. Для координации выполнения бизнес-функций, при- надлежащих различным системам компании, необходимо создать компонент управления распределенным бизнес-процессом (рис. 1.5). Рис. 1.5. Распределенный бизнес-процесс Распределенный бизнес-процесс и SOA-архитектура имеют много общего. Так, все требуемые бизнес-функции могут быть представлены в виде служб, а бизнес-процесс реализован внутри обращающегося к этим службам приложения. До сих пор мы рассматривали взаимодействие между приложениями и бизнес- функциями внутри компании. Однако во многих случаях требуемая функциональность
50 Глава 1. Решение задач интеграции с помощью шаблонов проектирования обеспечивается внешними организациями. К примеру, компания-перевозчик может предоставлять заказчикам службу, позволяющую проследить за доставкой товара. Часто интеграция приложений затрагивает бизнес-партнеров. Например, заказчик может обра- титься к розничному продавцу с тем, чтобы узнать стоимость и наличие в продаже опре- деленного товара. Если нужного товара нет на складе, розничный продавец обращается к поставщику для того, чтобы узнать, когда будет доставлен этот товар. Большинство принципов В2В-интеграции (рис. 1.6) аналогичны принципам интеграции приложений внутри компании. Взаимодействие через Интернет или какую-либо другую сеть, как правило, приводит к возникновению новых задач, относящихся к транспортным прото- колам и безопасности. Поскольку многие бизнес-партнеры предпочитают электронный фор- мат общения, на первый план выходит также вопрос стандартизации форматов данных. Рис. 1.6. В2В-интеграция Слабое связывание X Одним из наиболее популярных терминов в области интеграции корпоративных при- ложений является термин слабое связывание. Дуг Кэй (Doug Kaye) посвятил этой везде- сущей концепции целую книгу [20]. Преимущества слабого связывания были известны давно, однако ключевое место эта концепция заняла благодаря растущей популярности архитектур на основе Web-служб. Основной принцип слабого связывания состоит в уменьшении числа допущений, которые делают друг о друге взаимодействующие стороны (компоненты, приложения, службы, программы, пользователи). Несмотря на то что наличие дополнительной ин- формации об участниках и используемом протоколе позволяет повысить эффективность общения, получаемое при этом решение крайне неустойчиво к изменениям. Наглядным примером сильного связывания является вызов локального метода, осно- вывающийся на огромном числе допущений между вызываемой и вызывающей подпро- граммами. Оба метода должны выполняться в одном и том же процессе (например, вир- туальной машине) и быть написаны на одном и том же языке программирования (по крайней мере, использовать общий промежуточный язык или байт-код). Вызываю- щий метод передает вызываемому методу заранее известное число параметров опреде- ленного типа. Вызов локального метода происходит мгновенно, т.е. вызываемый метод получает управление сразу же после осуществления его вызова. Вызывающий метод мо- жет продолжить свое выполнение только после завершения работы вызываемого метода (таким образом, вызов локального метода является примером синхронного взаимодейст- вия). Выполнение вызывающего метода будет продолжено с оператора, следующего непосредственно после вызова метода. Мгновенный характер взаимодействия между вы- зываемым и вызывающим методами позволяет исключить возможность нарушения безо- пасности. Все эти предположения способствуют разработке хорошо структурированных приложений, функциональность которых разделяется между множеством вызывающих
Пример простой интеграции 51 друг друга методов. Наличие большого числа простых методов обеспечивает возможность их повторного использования и как следствие — гибкость приложения. Большое число подходов к интеграции приложений основывается на реализации уда- ленного взаимодействия с использованием семантики вызова локального метода. Данная стратегия получила название вызов удаленной процедуры (Remote Procedure Call — RPC) или вызов удаленного метода (Remote Method Invocation — RMI) и была поддержана раз- работчиками различных популярных платформ и инфраструктур: CORBA [51], Microsoft DCOM, .NET Remoting, Java RMI и, наконец, Web-служб в стиле RPC. Реализация уда- ленного взаимодействия с использованием семантики вызова локального метода имеет два очевидных преимущества. Во-первых, семантика синхронного вызова метода очень хорошо известна разработчикам приложений. Во-вторых, использование одинакового синтаксиса вызова локальных и удаленных методов позволяет отложить принятие реше- ния о том, какие компоненты должны выполняться локально, а какие— удаленно, вплоть до развертывания приложения. К сожалению, удаленное взаимодействие несовместимо со многими предположения- ми, касающимися вызова локального метода. Более того, использование одинаковой семантики для вызова локального и удаленного методов ошибочно и может привести к нежелательным результатам. Еще в 1994 году Вальдо (Waldo) и его коллеги из Sun Microsystems предупреждали о том, что “методы работы с объектами, взаимодействую- щими в распределенной системе, существенно отличаются от методов работы с объекта- ми, взаимодействующими в общем адресном пространстве” [50]. Следует ли приложе- нию использовать только те удаленные службы, которые написаны на одинаковом с ним языке программирования? Вызов удаленного метода может потребовать на несколько порядков больше времени, чем вызов локального метода. Должен ли вызывающий метод ожидать завершения выполнения вызываемого метода? Что если в результате сбоя в сети вызываемый метод окажется временно недоступным? Как долго следует ждать? Можно ли быть уверенным в том, что мы вызываем нужный нам, а не “подставной” метод? Как исключить возможность подслушивания? Что произойдет в результате изменения сигнатуры (списка принимаемых параметров) вызываемого метода? Следует отметить, что в случае поддержки удаленного метода третьей стороной (например, бизнес- партнером) подобные изменения выходят за пределы нашего контроля. Можно ли допус- тить сбой вызова метода или необходимо попытаться подобрать параметры, позволяю- щие осуществить вызов? Становится очевидно, что удаленное взаимодействие нельзя организовывать в соответствии с теми же допущениями, что и локальный вызов метода. Результатом применения архитектур, основанных на сильном связывании, при инте- грации удаленных приложений являются неустойчивые, трудно поддерживаемые и плохо масштабируемые решения. Многие из “пионеров” Web-служб убедились в этом на соб- ственном горьком опыте. Пример простой интеграции Продемонстрируем негативный эффект сильного связывания и способ его преодоле- ния на конкретном примере интеграции. Предположим, что нам необходимо создать ин- терактивную банковскую систему, позволяющую клиентам перечислять средства на свой счет путем денежного перевода из другого банка. Для достижения такой функционально-
52 Глава 1. Решение задач интеграции с помощью шаблонов проектирования сти интерфейсное Web-приложение должно быть интегрировано с серверной финансо- вой системой, управляющей переводом средств. Наиболее простой способ объединения указанных систем заключается в использовании протокола TCP/IP. За последние 15 лет стек протоколов TCP/IP был включен практически во все операционные системы и библиотеки программирования. TCP/IP— это самый рас- пространенный коммуникационный протокол, обеспечивающий передачу данных между миллионами компьютеров, подключенных к Интернету и локальным сетям. Предположим также, что удаленная функция, зачисляющая средства на счет клиента, принимает в качестве параметров только имя клиента и сумму денежного перевода. Следующие строки кода вызывают указанную функцию с помощью протокола TCP/IP (мы выбрали в качестве языка программирования С#, однако данный пример выглядит практически идентично, будучи написанным на С или Java): String hostName = "f inance.bank.com"; int port = 80; IPHostEntry hostinfo = Dns.GetHostByName(hostName); IPAddress address = hostinfo.AddressList[0]; IPEndPoint endpoint = new IPEndPoint(address, port); Socket socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(endpoint); byte[] amount = BitConverter.GetBytes(1000); byte[] name = Encoding.ASCII.GetBytes("Joe"); int bytesSent = socket.Send(amount); bytesSent += socket.Send(name); socket.Close(); Приведенный выше код создает сокет с адресом f inance. bank. com и пересылает по сети два элемента данных (сумму перевода и имя клиента). Таким образом, десять строк кода заменяют собой сложное связующее ПО наподобие средств ЕА1 или инструмента- рия RPC. К сожалению, указанный метод интеграции не лишен ряда существенных недостат- ков. Одной из наиболее сильных сторон протокола TCP/IP является его широкая под- держка различными операционными системами и языками программирования. Однако же независимость TCP/IP от платформы справедлива лишь по отношению к передаче самых простых структур данных: потоков байтов. Чтобы преобразовать данные в поток байтов, в приведенном выше коде был использован класс Bitconverter. Этот класс преобразовывает данные любого типа в массив байтов на основе их внутреннего пред- ставления в памяти. Подвох состоит в том, что внутреннее представление в памяти це- лого числа зависит от конкретной компьютерной системы. К примеру, платформа .NET использует для представления целого числа 32 бит, в то время как некоторые другие платформы— 64 бит. В рассмотренном выше примере по сети передаются 4 байт, кото- рые представляют одно 32-битовое целое число. Система, использующая для представ-
Пример простой интеграции 53 ления целого числа 64 бит, считает из сети 8 байт и, таким образом, “захватит” часть бай- тов, приходящихся на имя клиента. Кроме того, различные компьютерные системы используют для хранения целочис- ленных данных формат с разным порядком следования байтов— прямым (начиная с младшего байта) и обратным (начиная со старшего байта). Предположим, что система, использующая прямой порядок следования байтов, передает по сети 4 байт: 232 300 232 + 3 х 28 = 1000. Система, использующая обратный порядок следования байтов, интерпретирует полученную информацию как 232 х 234 + 3 х 216 = 3 892 510 720. Наш кли- ент стал настоящим богачом! Другими словами, предложенный подход может быть спра- ведлив только при допущении, что все компьютерные системы используют для хранения целочисленных данных формат с одинаковым порядком следования байтов. Второй недостаток указанного метода интеграции заключается в указании адреса уда- ленного компьютера с помощью DNS-имени (finance. bank. com). Для преобразования имени компьютера в IP-адрес существует служба DNS, однако что произойдет в случае перемещения функции зачисления средств на другой компьютер, принадлежащий дру- гому домену? К тому же, если компьютер даст сбой, нам может понадобиться обратиться к другому компьютеру с другим DNS-именем. Каждый из указанных сценариев предпо- лагает внесение изменений в существующий программный код. Зависимость кода вызова функции зачисления средств на счет клиента от адреса конкретного компьютера в сети нужно устранить. Использование для удаленного взаимодействия протокола TCP/IP устанавливает временную зависимость между общающимися системами. Как известно, протокол TCP/IP является протоколом с установкой соединения. Это означает, что фактической передачи информации между двумя системами предшествует стадия установки соедине- ния (рис. 1.7). При создании TCP-соединения отправитель и получатель данных обмени- ваются IP-пакетами. Если хотя бы один из трех компонентов взаимодействия — компью- тер отправителя, сеть или компьютер получателя—даст сбой, установка ТСР-соедине- ния окажется невозможной. Рис. 1.7. Пример взаимодействия сильносвязанных приложений Наконец, даже такое простое взаимодействие основано на использовании строгого формата данных. Первые 4 байт передаваемой информации соответствуют сумме денег, последующие—имени клиента. Введение третьего параметра, такого как название валю- ты, привело бы к необходимости внесения изменений в программный код как на стороне отправителя, так и на стороне получателя данных.
54 Глава 1. Решение задач интеграции с помощью шаблонов проектирования В рассмотренном выше примере “простой” интеграции взаимодействие систем осно- вывается на следующих предположениях. • Платформа—одинаковое внутреннее представление целых чисел и объектов. • Расположение — неизменяемый адрес компьютера. • Время— все компоненты интегрированной системы должны быть доступны в одно и то же время. • Формат данных—неизменяемый набор и параметров. Как отмечалось ранее, степень связывания характеризуется количеством допущений, которые делают друг о друге взаимодействующие стороны. Очевидно, что предложенный нами подход к интеграции Web-приложения с банковской системой является типичным примером сильного связывания. К счастью, число зависимостей, “связывающих” интегрируемые системы, можно уменьшить. Прежде всего, перейдем к использованию стандартного, не зависящего от платформы формата данных, такого как XML. Вместо пересылки данных непосредст- венно на компьютер получателя направим их в адресуемый канал. Канал— это логиче- ский адрес, известный как отправителю, так и получателю данных. Использование кана- лов позволяет устранить зависимость от размещения интегрируемых систем, однако все еще сохраняет требование об их одновременной доступности (если канал будет реализо- ван с помощью протокола, ориентированного на установку соединения). Чтобы изба- виться от этого недостатка, следует организовать очередь запросов, которые будут накап- ливаться в ней при недоступности сетевого соединения или системы-получателя. Помес- тив запрос в канал, отправитель может больше не заботиться о его доставке. Создание очереди запросов предполагает разбиение последних на сообщения—единицу буфериза- ции и отправки информации. Интегрируемые системы все еще связаны одинаковым форматом данных, однако эта зависимость может быть легко устранена за счет поддерж- ки преобразования данных в канале. Если формат одной системы меняется, все, что нужно сделать,—это изменить преобразователь, а не другую систему. В наибольшей сте- пени выгода от наличия преобразователя данных ощущается при интеграции множества приложений, размещающих данные в одном и том же канале. Общий формат данных, асинхронное взаимодействие по каналам с очередями и пре- образователи позволяют перейти от сильно- к слабосвязанному решению (рис. 1.8). Отправитель больше не зависит от внутреннего формата данных или размещения получа- теля. Более того, после помещения данных в канал отправитель может и вовсе не забо- титься об их доставке. Устранение зависимостей между интегрируемыми системами позволяет воспользоваться главным преимуществом слабого связывания— получить решение, устойчивое к изменениям. Наиболее существенный недостаток подобного под- хода состоит в увеличении сложности решения, которое теперь уже нельзя будет описать десятью строками программного кода. В этом случае следует прибегнуть к услугам свя- зующего ПО, ориентированного на обмен сообщениями. Компоненты подобной инфра- структуры описываются в следующем разделе этой главы.
Компоненты слабосвязанного интеграционного решения 55 Web- приложение Канал Финансовая система <deposit> <amt>1000</amt> <acct>Joe</acct‘ </deposit> Документ с самоописанием Рис. 1.8. Пример взаимодействия слабосвязанных приложений Является ли слабое связывание панацеей? Однозначного ответа здесь нет. Наряду с очевидными преимуществами, такими как гибкость и масштабируемость, слабое свя- зывание подразумевает использование сложной программной модели, что существенно затрудняет проектирование, создание и поддержку интеграционного решения. Компоненты слабосвязанного интеграционного решения Объединение двух систем с помощью интеграционного решения предполагает использование связующего ПО. Рассмотрим типичные компоненты связующего ПО, ориентированного на обмен сообщениями. Основной причиной интеграции приложений является необходимость налаживания обмена данными между ними. Примером данных, передаваемых между приложениями, является адрес заказчика, вызов удаленной службы или фрагмент HTML-кода информа- ционного портала. Передачу данных между приложениями обеспечивают два компонен- та интеграционного решения: сообщение и канал (рис. 1.9). Коммуникационный канал предназначен для обмена информацией между приложениями. В качестве канала может использоваться TCP/IP-соединение, общий файл, общая база данных и даже дискета. В канал помещается сообщение—фрагмент данных, который имеет одинаковое значение для обоих интегрируемых приложений. Объем информации, передаваемый с помощью одного сообщения, может быть как очень маленьким (например, телефонный номер заказчика), так и довольно большим (например, список всех заказчиков и адресов их проживания). Рис. 1.9. Основные элементы интеграционного решения, основанного на обмене сообщениями Администрирование системы
56 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Несмотря на то что передача сообщений по каналам уже может считаться “простой” формой интеграционного решения, не стоит останавливаться на достигнутом. Как пра- вило, разработчики интеграционного решения не могут изменять объединяемые прило- жения, в частности их внутренний формат данных. К примеру, одна из интегрируемых систем может хранить имя клиента с помощью полей first_name и last_name, а дру- гая— с помощью единственного поля Customer_Name. Поскольку возможность изме- нить внутренний формат данных приложений выпадает крайне редко, связующее ПО обязано обеспечить механизм преобразования форматов данных между приложениями. Предположим, что нам необходимо интегрировать более двух систем. Как изменится механизм обмена данными в этом случае? Наиболее простое решение состоит в указании системой-отправителем адресов систем-получателей сообщения. К примеру, при изме- нении адреса клиента система обслуживания заказчиков пересылает обновленную ин- формацию всем системам, хранящим адрес клиента. Данный подход имеет один сущест- венный недостаток— каждая система-отправитель должна поддерживать информацию обо всех системах-получателях сообщения. Как следствие добавление новой системы может потребовать внесения изменений в существующие системы интеграционного решения. Было бы гораздо лучше, если бы функция доставки сообщений получателям была возложена на связующее ПО, а именно на его маршрутизирующий компонент, такой как брокер сообщений. Как правило, со временем все интеграционные решения становятся слишком слож- ными. Приложения, форматы данных, каналы, маршрутизаторы, преобразователи — все эти элементы зачастую распределены между множеством операционных платформ и географических размещений. С целью управления интеграционным решением свя- зующее ПО должно включать в себя подсистему администрирования. Основные задачи подсистемы администрирования состоят в отслеживании потоков данных, работоспо- собности компонентов и приложений, а также уведомлении о возникших ошибках. Казалось бы, мы учли все, что необходимо для создания полноценного интеграцион- ного решения, — компоненты передачи данных, преобразования формата, маршрутиза- ции сообщений и администрирования. Однако мы исходили из допущения, что интегри- руемые приложения могут самостоятельно помещать сообщения в канал. К сожалению, большинство унаследованных приложений, коммерческих приложений, а также прило- жений, созданных на заказ, изначально не предназначались для интеграции. Для “под- ключения” подобных приложений к интеграционному решению используется конечная точка сообщения — специализированный компонент или адаптер канала {Channel Adapter, с. 154), предоставленный разработчиком интеграционной платформы. Пример: “Приборы и устройства” Рассмотрим пример создания интеграционного решения, основанного на обмене сообщениями. Предположим, что вымышленная компания “Приборы и устройства” (ЙРУСТ) закупает у производителей два наименования продукции (приборы и устройст- ва) и реализует ее розничным потребителям через Интернет (рис. 1.10).
Пример: “Приборы и устройства" 57 Заказчики Поставщики Рис. 1.10. Экосистема ПРУСТ Сформулируем требования, предъявляемые к интеграционному решению (несмотря на очевидное упрощение, требования, подобные приведенным ниже, часто встречаются в реальной практике). • Размещение заказов. Клиент может разместить заказ через Интернет, по телефону или с помощью факса. • Обработка заказов. Обработка заказа выполняется в несколько этапов, включая проверку наличия товара на складе, отправку товара и выставление счета. • Проверка состояния заказа. Клиент может проверить состояние своих заказов. • Изменение адреса клиента. Клиент может изменить адрес доставки товара, а также адрес, по которому будет выслан счет, с помощью Web-приложения. • Обновление каталога товаров. Компания должна периодически обновлять каталог товаров, основываясь на данных из каталогов производителей. • Рассылка новостей. Клиенты могут подписаться на рассылку новостей от ПРУСТ. • Тестирование и мониторинг. Сотрудники, ответственные за поддержку интеграци- онного решения, должны иметь возможность мониторинга всех его компонентов и потоков сообщений. Рассмотрим реализацию каждого из описанных выше требований по отдельности. Начав с “простой” формы интеграционного решения, мы постепенно перейдем к более сложным концепциям, таким как диспетчер процессов (Process Manager, с. 325). Внутренние системы IT-инфраструктура ПРУСТ состоит из множества различных приложений, как ком- мерческих, так и созданных на заказ. На рис. 1.11 показаны внутренние системы ПРУСТ. ПРУСТ располагает четырьмя каналами взаимодействия с клиентами: Web-сайт, центр обработки звонков, факс и электронная почта.
58 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Биллинг/ учет Web-интерфейс ПРУСТ Доставка Центр обработки звонков Склад приборов Каталог приборов Входящие факсы Склад устройств Исходящая почта Каталог устройств Рис. 1.11. IT-инфраструктура ПРУСТ В число внутренних систем ПРУСТ входят система бухгалтерского учета, выполняю- щая часть биллинговых функций, и система доставки товаров. Кроме того, ПРУСТ имеет две системы управления складскими запасами и две системы торговли по каталогу. Наличие одинаковых систем объясняется тем, что изначально ПРУСТ торговала только приборами, однако затем поглотила розничного продавца устройств. Размещение заказов Размещение заказов—это одна из основных функций создаваемого решения. Заказы приносят прибыль, однако в настоящий момент они обрабатываются вручную, что вле- чет за собой большие накладные расходы. Клиент ПРУСТ может разместить заказ с помощью одного из трех каналов: Web-сайта, центра обработки звонков и факса. К сожалению, каждая система основана на применении различных технологий и форматов данных. Система обработки звонков представляет собой коммерческое приложение, Web-сайт— 12ЕЕ-приложение, создан- ное на заказ, а система обработки входящих факсов использует ручной ввод данных в приложение Microsoft Access. Очевидно, что способ обработки заказа не должен зави- сеть от способа его размещения. Например, заказав товар с помощью центра обработки звонков, клиент должен иметь возможность проверить состояние заказа с помощью Web-приложения. Поскольку размещение заказа— это асинхронный процесс, охватывающий несколь- ко различных систем, унифицируем его с помощью связующего ПО, ориентированного на обмен сообщениями. Приложение в центре обработки звонков не обладает средства- ми для интеграции и должно быть подключено к системе обмена сообщениями с помо- щью адаптера канала (Channel Adapter, с. 154). Адаптер канала— это компонент, кото- рый публикует сообщения в канале сообщений (Message Channel, с. 93) при возникновении события в приложении. В некоторых случаях приложение может и вовсе не знать о наличии подключенного к нему адаптера канала. Например, приложение, сохраняю- щее информацию в базе данных, можно подключить к системе обмена сообщениями с помощью триггеров, срабатывающих при добавлении новых строк в определенные таб- лицы базы данных и помещающих соответствующие сообщения в канал сообщений.
Пример: “Приборы и устройства” 59 Адаптер канала может выполнять и обратную функцию, извлекая сообщения из канала сообщений и инициируя определенные действия внутри приложения. Для подключения к системе обмена сообщениями приложения, применяющегося для обработки входящих факсов, воспользуемся адаптером канала, соединенным с базой данных этого приложения. Поскольку Web-приложение разрабатывалось на заказ, созда- дим внутри него конечную точку сообщения (Message Endpoint, с. 124). Чтобы отделить код Web-приложения от кода конечной точки сообщения, применим шлюз обмена сообщениями (Messaging Gateway, с. 482). Каждая система размещения заказов использует для их представления разные форма- ты данных. С целью приведения этих форматов к общему формату сообщения, соответ- ствующего канонической модели данных (Canonical Data Model, с. 367), используются три транслятора сообщений (Message Translator, с. 115). Каноническая модель данных определя- ет формат сообщений, не зависящий от конкретного приложения. Таким образом, изме- нение внутреннего формата данных приложения затрагивает только транслятор сообще- ний, расположенный между этим приложением и общим каналом сообщений. Все остав- шиеся приложения, а также соответствующие им трансляторы сообщений, не требуют внесения изменений. Использование канонической модели данных приводит к разделению всех сообщений на две категории: канонические сообщения (общие) и сообщения при- ложений (частные). Сообщение приложения должно обрабатываться только создавшим его приложением и соответствующим транслятором сообщений. Условимся использовать в именах каналов сообщений, по которым передаются сообщения приложений, соответст- вующий префикс, например web_new_order. Имена каналов, по которым передаются канонические сообщения, будут лишены подобного префикса, например NEW_ORDER. Так как сообщение о размещении нового заказа должен был принять единственный по- лучатель, каждый адаптер канала подключается к транслятору сообщений с помощью кана- ла “точка-точка” (Point-to-Point Channel, с. 131). Следует отметить, что мы могли бы обой- тись без транслятора сообщений Web-приложения, запрограммировав логику преобразова- ния в соответствующем шлюзе обмена сообщениями. Однако подобная реализация функций преобразования может привести к возникновению ошибок программирования, а также на- рушить целостность предложенного ранее подхода к унификации формата сообщений. Все трансляторы сообщений размещают сообщения в канале “точка-точка” new_order, что устраняет различие между заказами, поступившими из разных источников (рис. 1.12). Канал сообщений NEW_ORDER является так называемым каналом типа данных (Datatype Channel, с. 139), поскольку по нему передаются сообщения одного и того же типа: сооб- щения о размещении нового заказа. Это облегчает задачу обработки сообщений, посту- пающих по каналу new_order. Само же сообщение о размещении нового заказа пред- ставляет собой сообщение с данными документа (Document Message, с. 171), основное на- значение которого состоит в передаче данных между приложениями. Обработка заказов Обработка заказа предполагает выполнение следующих действий. • Проверка кредитной репутации клиента. Если у клиента остались неоплаченные счета, следует отменить новый заказ. • Проверка наличия товара. Компания не сможет выполнить заказ, если в него будут включены отсутствующие в данный момент на складе товары.
60 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Конечная точка Канал Транслятор сообщений Адаптер канала Сообщение о размещении нового заказа Рис. 1.12. Обработка заказов, принятых из трех различных источников • Отправка товара и выставление счета (при условии положительной кредитной репутации клиента и наличия товара на складе). Указанную последовательность событий можно воспроизвести с помощью диаграм- мы операций UML (Unified Modeling Language—унифицированный язык моделирова- ния). Подобные диаграммы удобно применять для представления процессов, включаю- щих параллельные действия. Семантика диаграмм операций UML очень проста: после- довательные действия соединяются стрелками, а параллельные— толстыми линиями, представляющими операции ветвления и объединения. Операция ветвления подразуме- вает одновременное начало выполнения всех исходящих действий, а операция объедине- ния предписывает дождаться завершения выполнения всех входящих действий. Как показано на рис. 1.13, задачи проверки кредитной репутации клиента и наличия товара на складе выполняются параллельно. Толстая линия, соответствующая операции объединения, предписывает дождаться завершения выполнения обеих задач перед вы- полнением следующего действия. Если оба условия соблюдены, заказ передается на выполнение. В противном случае выполняется действие по обработке ошибки— компа- ния может напомнить клиенту оплатить последний счет или уведомить об отсрочке вы- полнения заказа. Поскольку настоящая книга посвящена проектированию интеграцион- ных решений, а не моделированию последовательно выполняемых операций, мы не бу- дем останавливаться на аспектах обработки ошибок. Более подробно эта тема рас- сматривается в [23] и [35].
Пример: “Приборы и устройства” 61 Рис. 1.13. Диаграмма операций, выполняемых при обработке заказа Действия, представленные на диаграмме операций, соответствуют различным систе- мам ПРУСТ. Система бухгалтерского учета проверяет кредитную репутацию клиента, система управления складскими запасами — наличие товара на складе, а система достав- ки товара отправляет товар клиенту. Выставляя клиенту счет, система бухгалтерского учета берет на себя также некоторые функции биллинга. Таким образом, обработка зака- за представляет собой типичный пример распределенного бизнес-процесса. Преобразуя логику диаграммы операций в проект интеграционного решения, реали- зуем операцию ветвления с помощью канала “публикация-подписка” (Publish-Subscribe Channel, с. 134), а операцию объединения— с помощью агрегатора (Aggregator, с. 283). Канал “публикация-подписка” отправляет сообщение всем активным потребителям, в то время как агрегатор объединяет несколько входящих сообщений в одно исходящее со- общение (рис. 1.14). Как показано на рис. 1.14, канал “публикация-подписка” передает сообщение о разме- щении нового заказа системе бухгалтерского учета и системе управления складскими за- пасами. Агрегатор объединяет сообщение о проверке кредитной репутации клиента и со- общение о проверке наличия товара на складе, после чего передает полученный результат маршрутизатору на основе содержимого (Content-Based Router, с. 247). Маршрутизатор на основе содержимого— это компонент, который принимает сообщение, а затем помешает его в один из нескольких каналов на основе некоторого правила. На диаграмме операций UML маршрутизатору на основе содержимого соответствует ромб. Если результат провер- ки заказа системой бухгалтерского учета и системой управления складскими запасами
62 Глава 1. Решение задач интеграции с помощью шаблонов проектирования оказался положительным, сообщение направляется в канал validated_order. Послед- ний является каналом “публикация-подписка", что позволяет передать сообщение как системе доставки товара, так и биллинговой системе. Если клиент не оплатил предыду- щий счет или нужного товара не оказалось на складе, маршрутизатор на основе содержи- мого направляет сообщение в канал invalid_order. Канал invalid_order связан с системой обработки ошибок (не показана на рисунке), которая уведомляет клиента о причине отклонения или задержки выполнения заказа. Агрегатор размещении нового заказа Рис. 1.14. Реализация процесса обработки заказа с помощью технологии асинхронного обмена сообщениями Доставка Канал “публикация- подписка” Биллинг/ учет INVALID_ORDER содержимого Описав основные этапы передачи сообщения, сосредоточимся на функции управле- ния складскими запасами. Как известно, компания ПРУСТ имеет две подобные систе- мы, соответствующие приборам и устройствам. Для корректной маршрутизации запро- сов о наличии товара на складе применим маршрутизатор на основе содержимого, как по- казано на рис. 1.15. В зависимости от первой буквы в коде товара (“П” или “У”) маршрутизатор на основе содержимого будет передавать все входящие запросы о наличии товара в соответствующую систему управления складскими запасами. Рис. 1.15. Маршрутизация запросов о наличии товара на складе Обратите внимание, что значение сообщения, передаваемого по каналу “точка- точка" (Point-to-Point Channel, с. 131) между маршрутизатором на основе содержимого и системой управления складскими запасами, отличается от значения сообщения, пере- даваемого по каналу “публикация-подписка”. Система управления складскими запасами получает сообщение с командой (Command Message, с. 169), предписывающей выполнить определенное действие (в данном случае—проверить наличие товара на складе). Поскольку системы управления складскими запасами приборов и устройств исполь- зуют различные внутренние форматы данных, преобразуем сообщение канонического
Пример: “Приборы и устройства” 63 формата в формат конкретной системы с помошью трансляторов сообщений (Message Translator, с. 115). Предположим, что первая буква в коде товара отлична от букв “П” и “У”. В этом случае маршрутизатор на основе содержимого направит сообщение в канал недопустимых сообще- ний (Invalid Message Channel, с. 143) INVALID_ORDER_ITEM. Следует подчеркнуть, что значе- ние сообщения зависит от канала, который используется для его транспортировки. Так, одно и то же сообщение, передаваемое по каналам new_order и invalid_order_ item, имеет два разных значения: заказ, предназначенный для выполнения, и заказ, содер- жащий ошибку. До сих пор мы предполагали, что все заказы содержат один элемент. Это может соз- дать неудобства для клиентов, так как им придется размешать отдельный заказ для каж- дого товара. К тому же обработка нескольких заказов, сделанных одним и тем же клиен- том, неизбежно приведет к возрастанию накладных расходов. К сожалению, включение в заказ нескольких элементов усложнит выбор системы управления складскими запаса- ми, применяющейся для проверки наличия товара на складе. На первый взгляд, эту про- блему можно решить за счет канала “публикация-подписка”, транспортирующего сооб- щение о размешении нового заказа обеим системам. Однако как в данном случае отли- чить заказ, содержащий ошибку? Очевидно, что идеальное решение заключается в добавлении к логике маршрутизатора на основе содержимого возможности обработки от- дельных элементов заказа. Выход из сложившейся ситуации заключается в использовании разветвителя (Splitter, с. 274)— компонента, разделяющего сообщение на несколько меньших частей. Как по- казано на рис. 1.16, разветвитель разделяет сообщение о размещении нового заказа на несколько сообщений о заказе товара, которые передаются соответствующей системе управления складскими запасами с помощью маршрутизатора на основе содержимого. Рис. 1.16. Обработка отдельных элементов заказа
64 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Проверив наличие товаров на складе, сообщения о заказе товара необходимо объеди- нить в одно сообщение. Для этого применим агрегатор— компонент, объединяющий несколько входящих сообщений в одно исходящее сообщение. Использование развет- вителя и агрегатора позволяет отделить обработку отдельных элементов заказа от обра- ботки заказа как одного целого. При создании агрегатора необходимо ответить на три ключевых вопроса. • Какие сообщения о заказе товара принадлежат к одному заказу? (Условие корре- ляции?) • Как определить, были ли получены все сообщения, принадлежащие к одному заказу? (Условие полноты?) • Как объединить несколько сообщений о заказе товара в одно сообщение о разме- щении нового заказа? (Алгоритм агрегации?) Поскольку клиент может разместить несколько последовательных заказов, судить о принадлежности сообщений к одному заказу по идентификатору клиента нельзя. А это значит, что нам необходимо ввести идентификатор самого заказа. Для этого добавим к процессу создания сообщения о размещении нового заказа расширитель содержимого (Content Enricher, с. 348), как показано на рис. 1.17. Расширитель содержимого— это компонент, добавляющий недостающие элементы данных к входящему сообщению. В данном случае расширитель содержимого используется д ля добавления уникального идентификатора к сообщению о размещении нового заказа. Адаптер Транслятор канала сообщении Рис. 1.17. Использование расширителя содержимого для добавления идентификатора к сообщению о размещении нового заказа Определим условие полноты сообщения и алгоритм агрегации. Поскольку агрегатор принимает все сообщения о заказе товара, включая заказы с ошибкой, условием полноты сообщения о размещении нового заказа может стать получение агрегатором определен- ного (заранее известного) числа сообщений о заказе товара с одинаковым идентифика-
Пример: “Приборы и устройства” 65 ционным номером. Алгоритм агрегации заключается в простой конкатенации сообще- ний о заказе товара в одно сообщение о размещении нового заказа. Полученное сооб- щение размещается агрегатором в канале validated_order. Поскольку комбинация разветвителя, маршрутизатора на основе содержимого и агрега- тора является неотъемлемой частью множества интеграционных решений, она заслужила статус отдельного компонента— так называемого обработчика составного сообщения (Composed Message Processor, с. 307). На рис. 1.18 показана обновленная диаграмма процесса обработки заказа, которая включает в себя символ обработчика составного сообщения. Канал “точка-точка Обработчик составного сообщения Биллинг/ учет Канал 4публикация- Сообщение о размещении нового заказа Проверка наличия товара Рис. 1.18. Обновленная диаграмма процесса обработки заказа с помощью технологии асинхронного обмена сообщениями Канал “публикация- Доставка Биллинг/ учет Агрегатор Маршрутизатор на основе invalid_order содержимого Проверка состояния заказа Несмотря на объединение систем с помощью каналов сообщений (Message Channel, с. 93), на выполнение заказа может уйти достаточно много времени. К примеру, нужного товара может не оказаться в наличии, в результате чего система управления складскими запасами будет удерживать сообщение о проверке возможности выполнения заказа до поступления товара на склад. В этом заключается одно из основных преимуществ асин- хронного обмена сообщениями— взаимодействие между системами осуществляется по мере готовности каждой из них. Пока система управления складскими запасами удержи- вает сообщение о проверке возможности выполнения заказа, система бухгалтерского учета может проверить кредитную репутацию клиента. При условии успешного выпол- нения обоих шагов агрегатор (Aggregator, с. 283) публикует сообщение, инициирующее отгрузку товара и формирование счета. Растянутость бизнес-процесса во времени также означает, что клиент и менеджеры компании могут захотеть узнать состояние заказа. Если определенного товара нет на складе, клиент может захотеть приобрести только те товары, которые есть в наличии. Кроме того, клиент должен иметь возможность узнать о состоянии доставки товара (дата отгрузки товара со склада, номер груза и т.п.). Текущий проект интеграционного решения не предусматривает возможность отслежи- вания состояния заказа. Сообщения, которые могут об этом свидетельствовать, проходят одновременно через несколько различных систем. Чтобы судить о состоянии заказа, необ- ходимо знать содержание последнего относящегося к нему сообщения. Одним из преиму- ществ канала “публикация-подписка” (Publish-Subscribe Channel, с. 134) является возмож- ность добавления к каналу новых подписчиков без нарушения хода сообщений. Использу- ем это свойство для отслеживания сообщений о размещении нового заказа, а также
66 Глава 1. Решение задач интеграции с помощью шаблонов проектирования сообщений о результатах проверки возможности выполнения заказа, и помещении их в хранилище сообщений (Message Store, с. 565). По сути, хранилище сообщений является базой данных, которую можно использовать для выяснения состояния заказа (рис. 1.19). Рис. 1.19. Для отслеживания состояния заказа используется хранилище сообщений Поскольку канал “точка-точка” (Point-to-Point Channel, с. 131) предусматривает дос- тавку сообщения единственному получателю, мы не можем добавить к нему нового под- писчика. Тем не менее мы можем воспользоваться отводом (Wire Тар, с. 558)— компо- нентом, извлекающим сообщение из одного канала и помещающего его в два других ка- нала. Схема, позволяющая извлечь сообщение из канала “точка-точка” и поместить его в хранилище сообщений, показана на рис. 1.20. Хранение сообщений в центральной базе данных имеет еще одно существенное пре- имущество. Первоначальный вариант проекта интеграционного решения предполагал передачу всех данных сообщения на каждом этапе его обработки. Так, сообщение о про- верке кредитной репутации должно было содержать не только идентификатор клиента, но и все данные исходного сообщения о размещении нового заказа. Если сообщение о размещении нового заказа будет содержаться в хранилище сообщений, компоненты ин- теграционного решения смогут получать нужные им данные из хранилища при предъяв- лении квитанции (Claim Check, с. 358). Недостаток подобного подхода состоит в том, что доступ к центральной базе данных обладает меньшей надежностью, чем передача со- общений по асинхронным каналам. Канал Канал ‘точка-точка’ точка-точка Хранилище сообщений Рис. 1.20. Отслеживание сообщений с помощью отвода Отвод
Пример: “Приборы и устройства” 67 Итак, новый вариант интеграционного проекта предусматривает размещение сообще- ний в хранилище сообщений, а также использование последнего при обработке сообщений. Информация, содержащаяся в хранилище сообщений, позволяет определить следующий этап обработки сообщения, устраняя тем самым необходимость соединения компонентов ин- теграционного решения с помощью фиксированных каналов сообщений. К примеру, если в базе данных содержится положительный ответ на сообщение о проверке кредитной репута- ции клиента, а также положительный ответ на сообщение о проверке наличия товара на складе, это означает, что заказ может быть выполнен и его можно передать для дальнейшей обработки системе доставки товара и биллинговой системе. Ранее для принятия подобного решения использовался агрегатор, однако сейчас логику принятия решений можно реали- зовать непосредственно в хранилище сообщений. Фактически тем самым мы превращаем хранилище сообщений в диспетчер процессов {Process Manager, с. 325). Диспетчер процессов— это центральный компонент, управляющий потоками сооб- щений в системе (рис. 1.21). Диспетчер процессов обеспечивает две основные функции: • хранение данных сообщений (внутри “экземпляра процесса”); • определение следующего этапа обработки сообщения (посредством использова- ния “эталона процесса”). Шина служб Диспетчер процессов NEW ORDER □ □ Web-интерфейс База данных заказов Биллинг/ учет Биллинг/ учет Доставка Проверить кредитную репутацию клиента Проверить наличие товара Доставить товар Отправить счет Рис. 1.21. Обработка заказов с помощью диспетчера процессов Новая архитектура превращает системы интеграционного решения (например, сис- тему управления складскими запасами) в общие бизнес-функции, доступные оставшим- ся компонентам в виде служб. Это упрощает поддержку решения и повышает возмож- ность повторного использования его элементов. Объединяющим фактором для отдель- ных служб может стать как поток сообщений (например, проверка наличия отдельных элементов заказа с помощью обработчика составного сообщения {Composed Message Processor, с. 307)), так и диспетчер процессов. Тем не менее диспетчер процессов позволяет
68 Глава 1. Решение задач интеграции с помощью шаблонов проектирования вносить изменения в поток сообщений гораздо проще, чем это можно было бы сделать с помощью предложенного ранее подхода. В соответствии с новой архитектурой все службы соединены с общей шиной служб, позволяющей вызывать службу любому компоненту интеграционного решения. IT-инфраструктуру ПРУСТ можно привести в соответствие с SOA-архитектурой, доба- вив функцию поиска службы в централизованном списке (каталоге) служб. Кроме того, все службы обязаны предоставить контракт интерфейса, описывающий функциональ- ность службы, а каждая служба типа “запрос-ответ” должна поддерживать концепцию обратного адреса (Return Address, с. 182). Обратный адрес позволяет вызывающему компо- ненту (потребителю службы) указать канал, по которому следует передавать сообщение с ответом. Это делает возможным использование одной и той же службы в нескольких различных контекстах, каждому из которых может соответствовать собственный канал для передачи ответных сообщений. Для хранения данных, относящихся к каждому экземпляру процесса, диспетчер про- цессов использует постоянное хранилище, такое как файл или реляционная база данных. Чтобы проверить состояние заказа с помощью Web-интерфейса, следует отправить сообщение диспетчеру процессов или выполнить запрос к базе данных заказов. Однако проверка состояния заказа является синхронным процессом, т.е. клиент ожидает полу- чить ответ немедленно. Поскольку Web-интерфейс представляет собой приложение, которое разрабатывалось на заказ, мы приняли решение обратиться к базе данных на- прямую. Общая база данных (Shared Database, с. 83) — наиболее простой и эффективный подход, позволяющий узнать состояние заказа за максимально короткое время. Единст- венный его недостаток заключается в сильном связывании Web-интерфейса и базы дан- ных. Впрочем, в этой ситуации подобный компромисс выглядит вполне допустимым. Большинство унаследованных систем разрабатывалось без встроенной поддержки та- ких концепций SOA-архитектуры, как обратный адрес. Чтобы представить эти системы в виде служб, следует воспользоваться интеллектуальным заместителем (Smart Proxy, с. 567). Интеллектуальный заместитель расширяет функциональность системы, перехва- тывая сообщения с запросом и сообщения с ответом, как показано на рис. 1.22. Интеллектуальный заместитель сохраняет информацию из сообщения с запросом (например, обратный адрес, указанный запрашивающей стороной), а затем применяет ее для обработки сообщения с ответом (например, помещает сообщение в нужный канал). Интеллектуальный заместитель также удобно использовать для отслеживания качества обслуживания (например, времени отклика) внешней службы. Интеллектуальный Рис. 1.22. Интеллектуальный заместитель позволяет представить унаследованную систему в виде общей службы
Пример: “Приборы и устройства” 69 Изменение адреса клиента Каждому клиенту ПРУСТ соответствует несколько различных адресов, например адрес доставки и адрес, на который высылается счет. Чтобы избежать дополнительных издержек, необходимо позволить клиенту самостоятельно изменять эти адреса с помо- щью Web-интерфейса. Для передачи обновленной информации в биллинговую систему, а также в систему доставки товара можно применить один из двух способов: • включать данные об адресах клиента в каждое сообщение о размещении нового заказа; • реплицировать обновленную информацию в каждую из систем. Преимущество первого подхода заключается в том, что для его реализации можно ис- пользовать существующие каналы интеграционного решения. В то же время это означает необходимость передачи дополнительной информации с каждым сообщением, хотя из- менение адреса клиента происходит не так уж и часто. При реализации первого подхода следует помнить, что биллинговая система и систе- ма доставки товара представлены коммерческими приложениями, не обладающими встроенными средствами интеграции. Следовательно, существует большая вероятность, что эти приложения будут использовать адреса, хранящиеся в собственной базе данных, а не адреса, полученные вместе с сообщением. Чтобы каждая из упомянутых систем обновляла адреса клиента на основе информации, содержащейся в сообщении о разме- щении нового заказа, воспользуемся диспетчером процессов (Process Manager, с. 325). Диспетчер процессов принимает сообщение о размещении нового заказа (содержащее адреса клиента), а затем передает биллинговой системе (системе доставки товара) два со- общения, как показано на рис. 1.23. Рис. 1.23. Включение данных об адресах клиента в сообщение о размещении нового заказа
70 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Следует помнить, что адаптеры канала {Channel Adapter, с. 154) принимают на вход частные сообщения, т.е. сообщения, отформатированные в соответствии с требованиями конкретного приложения. Поскольку сообщение о размещении нового заказа имеет канонический формат, его необходимо преобразовать с помощью транслятора сообщений (Message Translator, с. 115). Несмотря на то что логика преобразования может быть встроена в диспетчер процессов, использование внешних трансляторов сообщений являет- ся более предпочтительным (дополнительная функциональность может привести к воз- растанию сложности реализации диспетчера процессов). Второй подход к распространению обновленной информации об адресах клиента заключается в ее репликации. Как только клиент изменит один из своих адресов, эта ин- формация будет передана всем использующим ее системам с помощью канала “публикация-подписка” (Publish-Subscribe Channel, с. 134). Каждая система хранит адрес клиента с помощью внутренних механизмов и использует его при поступлении сообще- ния о размещении нового заказа. Данный подход позволяет уменьшить объем трафика сообщений (при условии, что клиенты будут размещать заказы чаще, чем изменять адре- са), а также снизить степень связывания систем. Всякая система, использующая адрес- ную информацию клиента, может подключиться к соответствующему каналу “публика- ция-подписка”, не затрагивая при этом другие системы. Поскольку клиент имеет несколько различных адресов (адрес доставки и адрес, на ко- торый высылается счет), следует позаботиться о том, чтобы системам передавались адре- са нужных типов. Другими словами, биллинговая система не должна получить сообще- ние об изменении адреса доставки товара. Эту функциональность можно обеспечить с помощью фильтров сообщений (Message Filter, с. 253), пропускающих только те сообще- ния, которые удовлетворяют определенному критерию (рис. 1.24). Как отмечалось выше, для преобразования канонического формата сообщений в формат, используемый приложениями, применяются трансляторы сообщений. Отсутст- вие транслятора сообщений Web-интерфейса объясняется тем, что формат последнего был взят за основу канонической модели данных (Canonical Data Model, с. 367). Это может ограничить гибкость решения, если мы захотим предоставить клиентам другой способ изменения своих личных данных, однако на данный момент такой подход выглядит вполне оправданным. Рис. 1.24. Репликация данныхоб адресах клиента с помощью канала “публикация-подписка”
Пример: “Приборы и устройства' 71 Поскольку обе системы хранят адреса клиентов в реляционных базах данных, обнов- ление последних осуществляется с помощью адаптеров канала. Так какой же из двух подходов к обновлению данных об адресах клиентов является более предпочтительным? В рассматриваемой ситуации объем трафика сообщений не превышает сотни заказов в день, поэтому оба способа вполне эффективны. Основным фактором, который может повлиять на выбор того или иного решения, является внут- ренняя структура используемых приложений. Некоторые приложения позволяют внести обновленные сведения в базу данных только через свой уровень бизнес-логики. К при- меру, приложение может провести дополнительную проверку адреса, создать запись в журнале событий и даже отправить клиенту электронное письмо с уведомлением о смене адреса. Выполнять все эти действия при обработке каждого заказа, конечно же, излишне. В данном случае имеет смысл прибегнуть ко второму подходу, т.е. проводить обновление личных данных клиента только при их фактическом изменении. В целом же мы отдаем предпочтение таким строго определенным, самодостаточным операциям, как “Изменить адрес” и “Разместить заказ”, потому что они допускают более гибкое управление бизнес-процессами. В конечном итоге все сводится к вопросу детализа- ции интерфейса и связанным с ней преимуществам и недостаткам. Интерфейсы с высокой степенью детализации могут замедлить работу системы по причине большого числа вызо- вов удаленных процедур или пересылаемых сообщений. К примеру, рассмотрим интер- фейс, предоставляющий отдельные методы для изменения полей в адресе клиента. Этот подход мог бы стать эффективным при условии, что взаимодействие происходит в пределах одного приложения. Если же речь идет об интеграционном решении, отправка шести или семи сообщений для обновления адреса клиента является непозволительной роскошью. Кроме того, интерфейсы с высокой степенью детализации предполагают сильное связыва- ние компонентов. Если к адресу клиента будет добавлено дополнительное поле, нам пона- добится внести изменения во все приложения, которые могут обновить адрес. Интерфейсы с низкой степенью детализации лишены описанных выше недостатков, однако слишком низкая степень детализации может существенно ограничить гибкость решения. Если операции “Отправить счет” и “Изменить адрес” будут объединены в одну внешнюю функцию, мы не сможем изменить адрес без отправки счета. Таким образом, нужно искать “золотую середину”, определяя степень детализации интерфейса, исходя из особенностей каждого конкретного сценария. Обновление каталога товаров Прежде чем разместить заказ, клиент должен ознакомиться с каталогом имеющихся в продаже товаров. Каталог товаров ПРУСТ составляется на основе соответствующих ка- талогов поставщиков. ПРУСТ позволяет своим клиентам одновременно просматривать оба типа товаров (приборы и устройства), а также включать их в один заказ. Подобная функциональность является типичным примером информационного портала—данные из нескольких источников объединяются в одном представлении. Оба поставщика обновляют каталоги своей продукции раз в три месяца. Следова- тельно, создавать инфраструктуру обмена сообщениями для передачи обновлений ката- логов от поставщиков в ПРУСТ не имеет смысла. Вместо этого воспользуемся таким способом интеграции, как передача файла (File Transfer, с. 80). Одним из преимуществ пе- редачи файла является возможность обеспечения надежной и эффективной доставки файлов по общедоступным сетям с помощью FTP или аналогичного ему протокола.
72 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Для сравнения: большинство инфраструктур асинхронного обмена сообщениями не мо- гут обеспечить надежного обмена данными через Интернет. Для преобразования формата каталогов поставщиков во внутренний формат ПРУСТ применяются трансляторы и адаптеры (рис. 1.25). Следует отметить, что трансляторы обрабатывают сразу весь каталог, а не его отдельные элементы. Этот подход хорошо за- рекомендовал себя при работе с большими объемами данных одинакового формата. Рис. 1.25. Обновление каталога товаров путем передачи файла Рассылка новостей Для повышения уровня продаж клиенты ПРУСТ должны периодически уведомляться о всевозможных специальных предложениях. Клиентам следует предоставить возможность выбора интересующих их новостей, а также сделать так, чтобы определенные новости были доступны только некоторым группам клиентов. К примеру, о некоторых акциях можно ин- формировать только привилегированных клиентов. Несмотря на то что рассылку данных нескольким получателям может обеспечить канал “публикация-подписка” (Publish-Subscribe Channel, с. 134), это решение имеет ряд существенных недостатков. Во-первых, канал “публикация-подписка” позволяет считывать опубликованные сообщения без уведомления издателя, а, как упоминалось выше, некоторая информация должна быть доступна только крупным заказчикам. Во-вторых, эффективное использование канала “публикация- подписка” возможно только в локальных сетях, поскольку передача копии сообщения всем получателям приводит к созданию избыточного объема сетевого трафика. Описанная выше функциональность может быть достигнута с помощью динамиче- ского списка получателей (Recipient List, с. 264) (рис. 1.26). Динамический список получа- телей представляет собой комбинацию двух маршрутизаторов сообщений (Message Router, с. 109): списка получателей и динамического маршрутизатора (Dynamic Router, с. 259). Список получателей— это маршрутизатор, рассылающий сообщения заданному набору получателей. Основное отличие списка получателей от канала “публикация-подписка” заключается в том, что список получателей предполагает жесткий контроль за получате- лями сообщения. Динамический маршрутизатор— это маршрутизатор, алгоритм кото- рого можно изменять с помощью управляющих сообщений. В рассматриваемом случае управляющие сообщения могут использоваться для уведомления маршрутизатора о предпочтениях клиентов (в получении каких новостей они заинтересованы).
Пример: “Приборы и устройства” 73 Рис. 1.26. Рассылка новостей с помощью динамического списка получателей Если клиенты получают новости по электронной почте, динамический список полу- чателей можно реализовать с помощью списка рассылки— функциональности, предо- ставляемой большинством систем для работы с электронной почтой. В этом случае каж- дый канал получателя будет соответствовать адресу электронной почты клиента. Если же клиенты получают новости через интерфейс Web-служб, каждый канал получателя будет представлен SOAP-запросом, а его адрес—унифицированным идентификатором ресур- са (URI) Web-службы. Этот пример наглядно демонстрирует независимость решения, основанного на использовании шаблонов проектирования, от конкретной технологии передачи данных. Тестирование и мониторинг Мониторинг потока сообщений является неотъемлемой частью процессов функцио- нирования и обслуживания интеграционного решения. Некоторые важные бизнес- метрики, такие как среднее время выполнения заказа, можно узнать с помощью храни- лища сообщений (Message Store, с. 565). Однако в процессе функционирования интеграци- онного решения может возникнуть потребность и в более детальной информации. Пред- положим, что для проверки кредитной репутации клиента привлекается внешнее кре- дитное агентство. Если кредитный рейтинг клиента слишком низкий, ему следует отказать в принятии заказа. Поскольку кредитное агентство является внешней организа- цией, ее услуги оплачиваются в соответствии с некоторым тарифом. Чтобы убедиться в корректности выставленного счета, следует сопоставить содержащиеся в нем сведения с фактической статистикой использования услуг кредитного агентства. Очевидно, что та- кой статистикой не может являться количество заказов, так как бизнес-логика интегра- ционного решения не предусматривает обращения к внешнему поставщику услуг для проверки кредитной репутации постоянных клиентов. К тому же между компанией и кредитным агентством может быть заключено соглашение о качестве обслуживания. Например, если время ответа на запрос о кредитной репутации клиента превысило опре- деленный порог, такой запрос не подлежит оплате.
74 Глава 1. Решение задач интеграции с помощью шаблонов проектирования Таким образом, чтобы собрать статистику использования услуг кредитного агентства, необходимо отслеживать количество запросов к внешней службе и время получения со- ответствующих ответов. В связи с этим рассмотрим две ситуации. Во-первых, поскольку внешняя служба может обрабатывать несколько запросов одновременно, необходимо предусмотреть механизм сопоставления запросов и ответов. Во-вторых, потребитель службы должен иметь возможность указать обратный адрес (Return Address, с. 182) — канал, по которому будет передаваться сообщение с ответом. Последнее требование является необходимым условием, позволяющим сопоставить сообщение с запросом к кредитному агентству и соответствующие сообщение с ответом. Описанная выше функциональность может быть реализована с помощью интеллек- туального заместителя (Smart Proxy, с. 567), расположенного между внешней службой и ее потребителями. Интеллектуальный заместитель перехватывает все запросы к службе и заменяет обратный адрес, указанный потребителем, фиксированным адресом канала, предназначенного для передачи сообщений с ответом. Другими словами, внешняя служ- ба помещает все сообщения с ответом в канал, указанный интеллектуальным заместите- лем. В свою очередь, интеллектуальный заместитель использует обратный адрес, содер- жащийся в сообщении с запросом, для выбора канала передачи ответа потребителю. Кроме того, интеллектуальный заместитель замеряет время, прошедшее между отправ- кой запроса внешней службе и получением от нее ответа на этот запрос. Полученные данные передаются по шине управления (Control Bus, с. 552) на консоль, как показано на рис. 1.27. Рис. 1.27. Использование интеллектуального заместителя для измерения скорости реагирования внешней службы Помимо ведения статистики обращений ко внешней службе, интеллектуальный заместитель может проводить мониторинг ее функционирования. Если кредитное агент- ство не ответило на запрос в течение определенного промежутка времени, консоли управления должно быть передано соответствующее сообщение. Гораздо сложнее зафик-
Резюме 75 сировать сбой в работе внешней службы, который может привести к выдаче ею неверных результатов. К примеру, если кредитное агентство будет определять отрицательный кре- дитный рейтинг для каждого клиента, компания может потерять множество заказов. Рассмотрим два механизма проверки результата, возвращаемого внешней службой. Во-первых, время от времени в поток запросов можно помещать тестовое сообщение (Test Message, с. 577), содержащее запрос о проверке клиента с заранее известной кредит- ной репутацией. Полученный результат следует передать верификатору тестовых данных, который сможет проверить степень точности возвращенного службой результата. Поскольку интеллектуальный заместитель поддерживает концепцию обратного адреса, генератор текстовых данных может указать канал, по которому будут передаваться тесто- вые сообщения с ответом (рис. 1.28). Во-вторых, для обнаружения сбоя в работе внешней службы можно применить стати- стическую выборку. Если по причине плохой кредитной репутации клиента отвергается в среднем один заказ из десяти, отклонение пяти заказов подряд может служить призна- ком сбоя в работе внешней службы или внутренней бизнес-логики. В этом случае кон- соль управления должна переслать все пять заказов администратору, который проверит правильность принятых решений. Запрос к кредитному агентству Запрос Клиент Проверка тестовых данных Генерация тестовых данных Ответ кредитного агентства Тестовый ответ Консоль управления Кредитное агентство Рис. 1.28. Использование тестового сообщения для проверки результата, возвращаемого внешней службой Ответ 1 Интеллектуальный заместитель Шина управления Резюме В этой главе был рассмотрен пример использования различных подходов к интегра- ции приложений, таких как передача файла (File Transfer, с. 80), общая база данных (Shared Database, с. 83) и асинхронный обмен сообщениями (Messaging, с. 87). Вы познакомились с ключевыми шаблонами для работы с потоком сообщений, такими как разветвитель (Splitter, с. 274), маршрутизатор сообщений (Message Router, с. 109), агрегатор (Aggregator, с. 283) и диспетчер процессов (Process Manager, с. 325). Несмотря на то что требования, предъявляемые к интеграционному решению, были намеренно упрощены, задачи, воз-
76 Глава 1. Решение задач интеграции с помощью шаблонов проектирования никающие при его реализации, часто встречаются на практике. Приведенные в главе диаграммы созданы с использованием универсальной нотации, не зависящей от конкрет- ной технологии или разработчика. Большинство приложений, объединенных в соответствии с рассмотренным сценари- ем интеграции, являются коммерческими приложениями. Более подробно интеграция приложений, созданных на заказ, рассматривается в главах 6 и 9. Оставшаяся часть книги посвящена подробному рассмотрению шаблонов интеграции корпоративных приложений. Для удобства чтения все шаблоны разделены на семь кате- горий: базовые шаблоны, шаблоны каналов, шаблоны сообщений, шаблоны маршрути- зации, шаблоны преобразования, шаблоны конечных точек и шаблоны системного администрирования.
Глава 2 Стили интеграции Введение Основная задача интеграции заключается в налаживании функциональных связей между приложениями— коммерческими и созданными на заказ, выполняющимися на различных программных платформах, распределенными между несколькими географи- ческими точками и т.п. Зачастую интегрируемые приложения не обладают встроенными средствами интеграции, а также находятся вне сферы административного влияния ком- пании. В этой главе рассматриваются различные способы интеграции приложений, каждый из которых предусматривает собственный уникальный подход к решению задач интеграции. Критерии интеграции приложений Основным критерием интеграции является необходимость налаживания взаимодей- ствия между приложениями. Если бы нам удалось создать приложение, не нуждающееся в обмене данными с другими приложениями, тема интеграции была бы исчерпана сама собой. На практике даже небольшая компания использует несколько различных прило- жений для предоставления необходимой функциональности своим сотрудникам, партне- рам и клиентам. Ниже перечислены основные критерии, влияющие на выбор способа интеграции приложений. • Связывание приложений. Зависимости между интегрированными приложениями должны быть сведены к минимуму. Сильное связывание предполагает наличие большого числа допущений между интегрированными приложениями. Изменение функциональности единственного приложения может привести к нарушению не- которых допущений и как следствие — к дестабилизации интеграционного реше- ния. Таким образом, интерфейсы объединяемых приложений должны обеспечи- вать необходимую функциональность, одновременно допуская возможность из- менения внутренней реализации. • Изменение приложений. Разработчикам интеграционного решения следует мини- мизировать изменения, вносимые в объединяемые приложения, а также объем кода, необходимого для интеграции. При этом нужно помнить, что стремление
78 Глава 2. Стили интеграции к минимизации изменений не должно идти вразрез со стремлением к достижению необходимой функциональности интеграционного решения. • Выбор технологии. Некоторые приемы интеграции требуют применения специали- зированного аппаратного и программного обеспечения. Привлечение дополнитель- ных средств может привести к существенному повышению стоимости проекта, воз- никновению зависимости от поставщика решений, а также к увеличению времени, требующегося на подготовку разработчиков интеграционного решения. С другой стороны, интеграции “с нуля” свойственны всевозможные непредвиденные обстоя- тельства, которые могут свести усилия разработчиков к “изобретению колеса”. • Формат данных. Интегрированные приложения должны использовать одинаковые форматы данных. Если этого требования не удается достичь ни с помощью встро- енных средств приложений, ни путем внесения в них изменений, для унификации формата данных применяются внешние трансляторы. • Своевременность доставки данных. Один из способов обеспечения своевременной доставки информации между приложениями предусматривает частый обмен ма- лыми порциями данных. К сожалению, этот подход оказывается неэффективным, если речь идет о передаче большого объема информации. В идеальном случае по- лучатель должен уведомляться о наличии данных, как только они будут доступны для считывания. Задержка в обмене данными может привести к рассинхронизации приложений, что, в свою очередь, увеличит сложность интеграционного решения. • Общая функциональность. Помимо обмена данными, многие интеграционные решения предусматривают использование приложениями общей функционально- сти. Несмотря на внешнюю схожесть, вызов функции удаленного приложения и вызов локальной функции имеют принципиальные отличия, способные оказать существенное влияние на интеграционное решение. • Удаленное взаимодействие. Большинство вычислительных процессов, выполняю- щихся внутри компьютера, синхронны. Другими словами, процедура ожидает за- вершения выполнения вызванной ею подпроцедуры. Поскольку вызов удаленной подпроцедуры гораздо медленнее локального вызова, удаленную подпроцедуру следует вызывать асинхронно, т.е. не дожидаться завершения ее выполнения. Асинхронное взаимодействие существенно повышает эффективность интеграци- онного решения, в то же время делая его более сложным в проектировании, разра- ботке и обслуживании. • Надежность. Удаленное взаимодействие гораздо менее надежно, чем вызов локальной функции. Процедура всегда может вызвать подпроцедуру внутри одного и того же приложения. К сожалению, вызов удаленной подпроцедуры свя- зан с определенными рисками, а именно с необходимостью корректного функ- ционирования сети и удаленного приложения. Надежное взаимодействие между интегрируемыми приложениями обеспечивает асинхронный подход, в соответст- вии с которым вызывающее приложение продолжает свою работу, не дожидаясь ответа от удаленной подпроцедуры. Таким образом, существует несколько различных критериев, влияющих на выбор способа интеграции приложений. Рассмотрим существующие подходы к интеграции и связанные с ними преимущества и недостатки.
Введение 79 Способы интеграции приложений Универсального способа интеграции приложений, в одинаковой степени удовлетво- ряющего всем рассмотренным выше критериям, не существует. Ниже перечислены основные стили интеграции приложений, известные на момент написания этой книги. • Передача файла (Hie Transfer, с. 80). Взаимодействие между приложениями осуще- ствляется с помощью файлов, в которые помещаются общие данные. • Общая база данных (Shared Database, с. 83). Взаимодействие между приложениями осу- ществляется с помощью базы данных, в которой сохраняется общая информация. • Удаленный вызов процедуры (Remote Procedure Invocation, с. 85). Взаимодействие между приложениями осуществляется с помощью удаленного вызова процедур, использующихся для выполнения действий или обмена данными. • Обмен сообщениями (Messaging, с. 87). Взаимодействие между приложениями осу- ществляется с помощью системы обмена сообщениями, которые используются для обмена данными и выполнения действий. Каждый стиль интеграции рассматривается далее в этой главе в виде шаблона проекти- рования. Все шаблоны имеют одинаковую постановку задачи—необходимость интегриро- вать приложения—и очень схожие контексты. Отличия между шаблонами заключаются в средствах, используемых для достижения результата. Шаблоны перечислены в порядке совершенствования предлагаемого решения, а также возрастания его сложности. Как отмечалось ранее, не существует универсального подхода к интеграции приложе- ний, однако существует способ, оптимальный в рамках конкретного интеграционного сценария. Каждый стиль интеграции имеет свои преимущества и недостатки. Интегра- ционное решение может основываться на использовании нескольких различных стилей. Подобные “гибридные” решения поддерживаются многими пакетами для интеграции и связующим ПО. Шаблоны проектирования, рассматривающиеся в остальных главах этой книги, отно- сятся к такому стилю интеграции, как обмен сообщениями. На наш взгляд, обмен сообще- ниями позволяет достичь оптимального баланса между критериями интеграции. Одно- временно это и самый сложный способ интеграции. Поскольку обмен сообщениями был положен в основу многих коммерческих EAI-продуктов, настоящая книга поможет вам подготовиться к их использованию.
80 Глава 2. Стили интеграции Передача файла (File Transfer) к к Мартин Фаулер (Martin Fowler) I ™ " Информационная система компании насчитывает множество приложений, создан- ных с использованием различных языков программирования и программных платформ. Как наладить взаимодействие и обмен данными между несколькими приложе- ниями? В идеальном мире информационная система организации состоит из единственного приложения, выполняющего все необходимые операции. В действительности даже самые маленькие компании используют несколько приложений для получения необхо- димой функциональности. Это обусловлено следующими причинами. • Организации приобретают программные пакеты, созданные сторонними разра- ботчиками. • Между приложениями, созданными в разное время, существуют технологические отличия. • Приложения, созданные разными разработчиками, имеют архитектурные отличия. • Своевременный выпуск приложения на рынок важнее наличия в приложении встроенных средств интеграции. В результате каждая организация вынуждена решать задачу обмена данными между приложениями, созданными с помощью различных языков программирования, предна- значенных для выполнения на разных программных платформах и реализующих разные подходы к управлению бизнес-процессами. Налаживание взаимодействия между подобными приложениями требует умения объединять приложения как на техническом уровне, так и на уровне бизнес-логики. Что- бы упростить интеграцию приложений, постарайтесь свести к минимуму объем значимой информации о функционировании каждого конкретного приложения. Одной из наиболее важных задач интеграции является создание общего механизма передачи данных, не зависящего от конкретной платформы или языка программирова- ния. Постарайтесь не использовать специализированные аппаратные или программные средства, а обойтись теми возможностями, которые уже есть в наличии. Файлы— это универсальный механизм хранения данных, встроенный в любую опе- рационную систему и поддерживающийся любым языком программирования. Таким об- разом, один из самых простых способов интеграции приложений может быть основан на использовании файлов. Одним из наиболее важных решений является выбор общего формата файлов. До не- давнего времени наиболее распространенным стандартным форматом файлов считался простой текстовый файл. Современные интеграционные решения основываются на ис- пользовании формата XML.
Передача файла (File Transfer) 81 Приложение, которому требуется передать данные другому приложению, сохра- няет их в файле. Ответственность за преобразование форматов файлов ложится на плечи разработчиков интеграционного решения. Частота создания файлов зависит от характера бизнес-логики компании. Также следует определить периодичность создания и считывания файлов приложе- ниями. Слишком частая работа с файлами может привести к нерациональному исполь- зованию ресурсов. Как правило, периодичность создания файлов (ежедневно, ежене- дельно, ежеквартально и т.д.) определяет бизнес-логика компании. Наиболее существенное преимущество файлов заключается в том, что разработчики интеграционного решения не нуждаются в дополнительных сведениях о внутренней реа- лизации интегрируемых приложений. Основная задача интеграторов заключается в пре- образовании форматов файлов (если это необходимо). Результатом подобного подхода является слабое связывание интегрируемых приложений. Единственными общедоступ- ными интерфейсами приложений являются создаваемые этими приложениями файлы. Простота реализации передачи файла обусловливается также отсутствием необходи- мости в привлечении дополнительных средств или пакетов для интеграции. Вместе с тем это приводит к возрастанию нагрузки, ложащейся на плечи разработчиков интеграцион- ного решения. Объединяемые приложения должны использовать общее соглашение об именовании и расположении файлов. Приложение, создающее файл, должно обеспечить уникальность его имени. Кроме того, необходимо разработать механизм удаления старых файлов, а также механизм блокировки доступа к файлу на время его записи. Если интег- рируемые приложения не имеют доступа к общему диску, следует также обеспечить ме- ханизм перенесения файлов между дисками. Один из наиболее существенных недостатков передачи файла заключается в возможно- сти рассинхронизации интегрируемых систем вследствие низкой частоты обмена инфор- мацией. Если заказчик изменит адрес доставки товара утром, а система обслуживания кли- ентов распространит эту информацию ночью, то на протяжении всего дня система доставки товаров будет иметь неверные сведения о месте назначения груза. Иногда рассинхрониза- ция допустима. В конечном итоге люди уже привыкли к тому, что на распространение ин- формации уходит какое-то время. Однако в некоторых случаях использование устаревшей информации может привести к крайне нежелательным последствиям. Таким образом, при определении частоты создания файлов следует всегда исходить из потребностей в наличии актуальной информации считывающих эти файлы приложений.
82 Глава 2. Стили интеграции При необходимости частоту создания файлов можно увеличить. В некотором смысле обмен сообщениями (Messaging, с. 87) сравним с передачей файла при каждом изменении в данных приложения. К сожалению, создание и обработка большого количества файлов может привести к нерациональному использованию вычислительных ресурсов. Более частый обмен данными согласованного формата обеспечивает общая база дан- ных (Shared Database, с. 83). Для интеграции функциональности приложений используйте удаленный вызов процедуры (Remote Procedure Invocation, с. 85). Наконец, для частого обме- на малыми порциями данных (возможно, инициирующими вызовы удаленных функций) применяйте обмен сообщениями.
Общая база данных (Shared Database) 83 Общая база данных (Shared Database) Мартин Фаулер (Martin Fowler) Информационная система компании насчитывает множество приложений, создан- ных с использованием различных языков программирования и программных платформ. Бизнес-логика компании предполагает быстрый и надежный обмен информацией между отдельными системами. Как наладить взаимодействие и обмен данными между несколькими приложениями? Основной недостаток передачи файла (File Transfer, с. 80) заключается в несвоевре- менном обмене данными между приложениями. Вместе с тем требование к работе с наи- более достоверными данными является стандартным для современного делового мира. Это не только уменьшает количество ошибок при принятии решений, но и повышает до- верие сотрудников к информации. Кроме того, передача файла не предъявляет требований к формату данных. Различия в восприятии одной и той же информации могут привести к возникновению проблем ин- теграции. К примеру, в контексте геологической базы данных термин “скважина” может быть определен как пробуренная скважина, заполненная водой или нефтью. В то же вре- мя в контексте базы данных, расположенной на производстве, термин “скважина” может означать несколько пробуренных скважин, объединенных одним нефтедобывающим оборудованием. Очевидно, что проблема семантического диссонанса гораздо серьезнее, нежели проблема несовместимости форматов данных. (Более подробно тема семантиче- ского диссонанса рассматривается в [21].) Чтобы избежать ее, следует хранить информа- цию в центральной базе данных, доступной для всех интегрируемых приложений. Интегрируемые приложения сохраняют информацию в общей базе данных (Shared Database), схема которой удовлетворяет требованиям всех приложений.
84 Глава 2. Стили интеграции Общая база данных обеспечивает согласованность хранящейся в ней информации. Все попытки изменения одного и того же фрагмента данных из нескольких различных источников будут пресекаться администратором транзакций базы данных. Наиболее простой подход к реализации общей базы данных заключается в использова- нии реляционной базы данных с поддержкой SQL. Язык запросов SQL поддерживается практически всеми платформами для разработки приложений, что позволяет не беспо- коиться о различии в форматах файлов и избавляет от необходимости изучения новой технологии. Наличие общей базы данных устраняет проблему семантического диссонанса. Все во- просы, связанные с интерпретацией данных, могут быть сняты на этапах проектирования и реализации интеграционного решения. Одной из наибольших трудностей, присущих рассматриваемому стилю интеграции, является разработка схемы общей базы данных. Создание унифицированной схемы дан- ных, удовлетворяющей требованиям нескольких различных приложений, связано со сложностями как технического, так и политического характера. Если применение уни- фицированной схемы данных приведет к снижению производительности критически важного приложения, руководство компании может настоять на необходимости пере- смотра интеграционного проекта. Еще одним камнем преткновения для реализации общей базы данных является ком- мерческое ПО. Большинство коммерческих приложений работает только со встроенной схемой данных, возможность адаптации которой зачастую оставляет желать лучшего. Ус- ложняет задачу также тот факт, что создатели коммерческого ПО склонны изменять схе- му данных с каждой новой версией своих продуктов. С возрастанием числа обращений к общей базе данных последняя может превратиться в узкое место интеграционного решения, что приведет к снижению производительности приложений и увеличению вероятности блокировки данных. Если интегрируемые при- ложения расположены в нескольких географических точках, доступ к центральной базе данных будет осуществляться по традиционно медленным линиям связи глобальных се- тей. Несмотря на то что распределение базы данных между приложениями позволит об- ращаться к ней по локальной сети, это лишь усложнит ситуацию. Интеграцию функциональности приложений (в отличие от интеграции их данных) обеспечивает удаленный вызов процедуры (Remote Procedure Invocation, с. 85). Для частого обмена малыми порциями данных различных типов (в отличие от использования унифи- цированной схемы данных) применяйте обмен сообщениями (Messaging, с. 87).
Удаленный вызов процедуры (Remote Procedure Invocation) 85 Удаленный вызов процедуры (Remote Procedure Invocation) Мартин Фаулер (Martin Fowler) Информационная система компании насчитывает множество приложений, создан- ных с использованием различных языков программирования и программных платформ. Бизнес-логика компании предполагает быстрый обмен информацией и функционально- стью между отдельными системами. Как наладить взаимодействие и обмен данными между несколькими приложениями? Несмотря на то что передача файла {File Transfer, с. 80) и общая база данных (Shared Database, с. 83) позволяют наладить обмен информацией между приложениями, зачастую этого оказывается недостаточно. К примеру, изменение адреса проживания клиента может потребовать выполнения некоторых действий, таких как проверка допустимости адреса. Одним из наиболее мощных механизмов структурирования приложений является ин- капсуляция, предусматривающая доступ к данным посредством манипулирующего эти- ми данными программного кода. Общая база данных представляет собой неинкапсулиро- ванную структуру, в то время как передача файла отличается замедленной реакцией на обновление данных. Неинкапсулированный характер общей базы данных затрудняет поддержку интегриро- ванных с ее помощью приложений. Изменения в приложении могут повлечь за собой из- менения в базе данных, что, в свою очередь, скажется на всех оставшихся приложениях. Как следствие организации, использующие общую базу данных, крайне неохотно относят- ся к необходимости ее изменения, что может затруднить реализацию новых бизнес- требований. Выходом из сложившейся ситуации могло бы стать создание механизма, позволяю- щего приложению вызывать функцию другого приложения и передавать ей для обработ- ки необходимые данные. Представьте каждое приложение в виде объекта или компонента, содержащего инкапсулированные данные и предоставляющего интерфейс для взаимодейст- вия с другими приложениями. Программа А Программа Б
86 Глава 2. Стили интеграции По сути, удаленный вызов процедуры представляет собой применение принципов ин- капсуляции данных к интеграции приложений. Если приложение нуждается в получении или изменении информации, поддерживаемой другим приложением, оно обращается к нему посредством вызова функции. Таким образом, каждое приложение самостоятельно обеспечивает целостность своих данных и может изменять их формат, не затрагивая при этом оставшиеся приложения. Удаленный вызов процедуры поддерживается множеством технологий, таких как CORBA, COM, .NET Remoting и Java RML Зачастую реализация удаленного вызова проце- дуры предусматривает наличие дополнительных возможностей, например, поддержки транзакций. Время написания этой книги пришлось на пик популярности Web-служб, использующих такой стандарт удаленного взаимодействия, как SOAP. Наличие методов, манипулирующих данными, способствует решению проблемы семантического диссонанса. Приложение может предоставить несколько интерфейсов к одним и тем же данным, тем самым позволяя “видеть” их под разными углами. Несмотря на внешнюю схожесть, удаленный вызов процедуры и вызов локальной функ- ции имеют принципиальные отличия, способные оказать существенное влияние на ин- теграционное решение [9, 50]. Следует отметить, что удаленный вызов процедуры характеризуется достаточно сильной степенью связывания приложений. Зачастую это обусловлено применением при разра- ботке интеграционного решения принципов, которые применяются при разработке от- дельного приложения, например принципа последовательного выполнения операций. Асинхронное взаимодействие слабосвязанных приложений, подразумевающее частый обмен малыми порциями данных (возможно, инициирующими вызовы удаленных функ- ций), обеспечивает обмен сообщениями {Messaging, с. 87).
Обмен сообщениями (Messaging) 87 Обмен сообщениями (Messaging) ??? I I Информационная система компании насчитывает множество приложений, создан- ных с использованием различных языков программирования и программных платформ. Бизнес-логика компании предполагает быстрый обмен информацией и функционально- стью между отдельными системами. Как наладить взаимодействие и обмен данными между несколькими приложениями? Передача файла (File Transfer, с. 80) и общая база данных (Shared Database, с. 83) позво- ляют приложениям получить доступ к общим данным, но не к общей функциональности. Удаленный вызов процедуры (Remote Procedure Invocation, с. 85) устраняет этот недостаток за счет сильного связывания интегрируемых приложений. Зачастую же задача интегра- ции заключается в обеспечении своевременного обмена данными между слабосвязанны- ми приложениями. Несмотря на то что передача файла не связывает объединяемые приложения, этот стиль интеграции не может обеспечить своевременной доставки данных. Напротив, об- щая база данных обеспечивает быструю доставку информации за счет сильного связыва- ния приложений. Удаленный вызов процедуры предполагает использование модели приложения в качест- ве основы интеграционного решения. Несмотря на внешнюю схожесть, вызов удаленной функции и вызов локальной функции имеют существенные отличия. Вызов удален- ной функции гораздо медленнее локального вызова и менее надежен, чем он. Сбой в ра- боте одного приложения может привести к сбою всех приложений, полагающихся на его функциональность. Оптимальное решение должно обладать характеристиками передачи файла, обеспечи- вая частый, асинхронный обмен малыми порциями данных с уведомлением получателя и механизмом повторной передачи. В отличие от общей базы данных сведения о представле- нии и хранении информации должны быть скрыты от интегрируемых приложений. Кро- ме того, приложение должно иметь возможность удаленного вызова процедуры другого приложения с гарантированным отсутствием сбоя. Используйте обмен сообщениями (Messaging) для быстрой, мгновенной, надеж- ной и асинхронной передачи данных изменяемого формата.
88 Глава 2. Стили интеграции Асинхронный обмен сообщениями устраняет большинство недостатков распределен- ных систем. Для передачи сообщения не требуется одновременной доступности отправи- теля и получателя. Более того, сам факт асинхронного обмена данными побуждает разра- ботчиков к созданию компонентов, не требующих частого удаленного взаимодействия. Подобно передаче файла система обмена сообщениями обеспечивает слабое связывание объединяемых приложений. Сообщения могут быть преобразованы во время передачи без уведомления отправителя или получателя. Слабое связывание позволяет разработчикам использовать различные способы доставки сообщений: широковещательную рассылку всем получателям, маршрутизацию сообщений одному получателю или их группе и т.п. Необходимость преобразования данных обусловлена наличием у приложений раз- личных концептуальных моделей, т.е. семантическим диссонансом. В отличие от общей базы данных, обмен сообщениями не предполагает использования специальных средств для его устранения. Это связано с тем, что семантический диссонанс неизбежно возникает при добавлении к интеграционному решению новых приложений (например, в результа- те слияния информационных систем компаний). Частый обмен небольшими порциями данных создает предпосылки для использова- ния приложениями общей функциональности. Если получение сообщения о размеще- нии нового заказа требует выполнения некоторых действий, они могут быть иницииро- ваны путем отправки специальных сообщений. Несмотря на то что скорость подобного взаимодействия ниже, чем при использовании удаленного вызова процедуры, вызывающей стороне не приходится ждать ответа на отправленное сообщение. На самом деле обмен сообщениями не такой уж и медленный— достаточно большое число систем обмена сообщениями используются финансовыми организациями для обработки тысяч котиро- вок акций в секунду. Поскольку настоящая книга посвящена обмену сообщениями, можно предположить, что ее авторы считают этот стиль интеграции приложений наиболее оптимальным. Вместе с тем не стоит забывать, что обмен сообщениями далеко не идеален. Отметим некоторые из присущих ему недостатков. Несмотря на то что высокая частота отправки сообщений суще- ственно снижает вероятность рассогласования данных, присущего передаче файла, она не позволяет полностью исключить задержку при доставке информации. Большинство разра- ботчиков не привыкли к “асинхронному” способу мышления, результатом чего стало появ- ление множества различных правил и приемов программирования. Кроме того, решения, основанные на обмене сообщениями, сложнее тестировать и отлаживать. Возможность преобразования сообщений позволяет обеспечить гораздо более слабую связность приложений, чем этого можно было бы достичь с помощью удаленного вызова процедуры. Вместе с тем подобная независимость означает дополнительную нагрузку на разработчиков интеграционного решения, которым приходится создавать множество строк связующего кода. Следующие вопросы и ответы помогут пролить свет на подробности реализации обме- на сообщениями. 4 Как обеспечивается передача пакетов данных? Отправитель помещает данные, оформленные в виде сообщения (Message, с. 98), в канал сообщений (Message Channel, с. 93), соединяющий его с получателем. ♦ Как отправитель определяет адрес получателя данных?
Обмен сообщениями (Messaging) 89 Если отправитель не знает адрес получателя данных, он пересылает сообщение мар- шрутизатору сообщений (Message Router, с. 109), который, в свою очередь, доставляет со- общение получателю. ♦ Как определить требуемый формат данных сообщения ? Если отправитель и получатель используют разные форматы данных, отправитель может передать сообщение транслятору сообщений (Message Translator, с. 115), который преобразует формат сообщения и передаст его получателю. ♦ Как подключить приложение к системе обмена сообщениями ? Для подключения к системе обмена сообщениями приложение должно реализовать конечную точку сообщения (Message Endpoint, с. 124).
г-4*4 ;«*»>'►••• nW<r" ; э '? r.a‘~ s :- .»*<.<
Глава 3 Системы обмена сообщениями Введение В главе 2 были рассмотрены различные стили интеграции приложений, включая обмен сообщениями (Messaging, с. 87). Обмен сообщениями позволяет наладить асинхрон- ное взаимодействие между слабо связанными приложениями. Передачу данных между интегрированными приложениями обеспечивает система обмена сообщениями. Основные концепции обмена сообщениями Как и большинство технологий, обмен сообщениями (Messaging, с. 87) характеризуется несколькими базовыми концепциями. • Каналы. Приложения, объединенные с помощью технологии обмена сообщения- ми, передают данные по каналам сообщений (Message Channel, с. 93). Изначально система обмена сообщениями не содержит каналов; они создаются по мере опре- деления способов взаимодействия приложений. • Сообщения. Сообщение (Message, с. 98) — это наименьшая единица данных, кото- рая может быть передана по каналу сообщений. Следовательно, для передачи дан- ных отправитель должен разбить их на пакеты, которые затем будут упакованы в сообщения и помещены в канал. Подобным образом получатель извлекает сооб- щения из канала и выделяет из них полезные данные. Система обмена сообще- ниями гарантирует доставку сообщений путем их повторной отправки. • Каналы и фильтры. В самом простом случае система обмена сообщениями достав- ляет сообщение непосредственно с компьютера отправителя на компьютер полу- чателя. Однако во многих ситуациях необходима промежуточная обработка от- правленного сообщения (например, преобразование формата или проверка соот- ветствия некоторым правилам) прежде, чем оно будет принято получателем. Архитектура каналов и фильтров (Pipes and Filters, с. 102) описывает процесс орга- низации многоэтапной обработки сообщения с использованием каналов. • Маршрутизация. Для того чтобы достичь конечной точки назначения, сообщению может потребоваться пройти через несколько различных каналов. Иногда слож- ность маршрута сообщения приводит к тому, что отправитель не может опреде-
92 Глава 3. Системы обмена сообщениями лить канал, в который необходимо поместить сообщение для его доставки получа- телю. В этом случае отправитель передает сообщение маршрутизатору сообщений (Message Router, с. 109)— программному компоненту, играющему роль фильтра в рамках архитектуры каналы и фильтры. Маршрутизатор определяет канал, в кото- рый необходимо поместить сообщение для его доставки конечному получателю или следующему маршрутизатору. • Преобразование. Зачастую отправитель и получатель используют различные фор- маты для представления одних и тех же данных. Для преобразования формата от- правителя в формат получателя сообщение должно пройти через промежуточный фильтр, получивший название транслятор сообщений (Message Translator, с. 115). • Конечные точки. Большинство приложений не обладает встроенными средствами интеграции. Для подключения таких приложений к системе обмена сообщениями необходим промежуточный код, учитывающий особенности приложения и систе- мы обмена сообщениями. Этот код является совокупностью конечных точек сооб- щения (Message Endpoint, с. 124), позволяющих приложению отправлять и прини- мать сообщения. Об организации книги Шаблоны, представленные в этой главе, позволяют получить базовое представление об интеграции приложений с помощью обмена сообщениями (Messaging, с. 87). Более под- робно каждый из представленных здесь корневых шаблонов рассматривается в одной из следующих глав книги (рис. 3.1). Рис. 3.1. Корневые шаблоны проектирования
Канал сообщений (Message Channel) 93 Канал сообщений (Message Channel) Компании необходимо наладить взаимодействие между двумя отдельными приложе- ниями с помощью обмена сообщениями (Messaging, с. 87). Как наладить взаимодействие между двумя приложениями с использованием технологии обмена сообщениями? Наличие системы обмена сообщениями не является достаточным условием для взаи- модействия подключенных к ней приложений. Другими словами, отправитель не может использовать систему обмена сообщениями для передачи информации получателю. Если бы это было так, система обмена сообщениями должна была бы обладать некими “магическими” свойствами (рис. 3.2). Приложение Система обмена сообщениями Отправитель Рис. 3.2. "Магическая” система обмена сообщениями Детерминированный обмен данными между приложениями обеспечивает набор соединений. Соедините приложения с помощью канала сообщений (Message Channel), дос- тавляющего помещенную в него информацию от отправителя к получателю. Приложение, которому необходимо отправить информацию, помещает ее не просто в систему обмена сообщениями, а в конкретный канал сообщений. Подобным образом приложение, которому необходимо получить информацию, обращается не просто к сис- теме обмена сообщениями, а к конкретному каналу сообщений. Система обмена сообщениями подразумевает наличие отдельных каналов сообщений для каждого типа передаваемой информации. Таким образом, отправитель помещает информацию не в произвольный канал сообщений, а в канал сообщений, предназначенный для передачи данных конкретного типа. Аналогично получатель извлекает информацию из канала сообщений, предназначенного для передачи именно этого типа информации. В действительности каналы представляют собой логические адреса в системе обмена сообщениями. Реализация каналов сообщений зависит от конкретной системы обмена сообщениями. К примеру, все конечные точки сообщения (Message Endpoint, с. 124) могут быть соединены друг с другом или подключены к центральному коммутатору, а несколь- ко логических каналов сообщений могут быть представлены одним физическим каналом.
94 Глава 3. Системы обмена сообщениями Как бы там ни было, логические каналы скрывают детали конкретной реализации от приложений. Система обмена сообщениями не содержит заранее сконфигурированных каналов со- общений. Требуемые каналы сообщений определяются на этапе проектирования инте- грационного решения и реализуются администратором системы обмена сообщениями. Несмотря на то что некоторые системы обмена сообщениями поддерживают создание новых каналов сообщений после начала эксплуатации интеграционного решения, это не позволяет распространить информацию о новых каналах между всеми приложениями. Следовательно, количество и назначение каналов сообщений необходимо определить до этапа развертывания интеграционного решения. (Об исключениях из этого правила рас- сказывается во введении к главе 4.) О словаре обмена сообщениями Существует несколько различных терминов, применяющихся для обозначения при- ложений, взаимодействующих посредством канала сообщений. Наиболее известными из них являются термины отправитель и получатель— приложение отправляет ин- формацию с помощью канала сообщений для ее получения другим приложением. Так- же популярны термины поставщик и потребитель. Приложения, взаимодействующие посредством канала “публикация-подписка” (Publish-Subscribe Channel, с. 134), известны как публикатор и подписчик (следует отметить, что эти термины часто употребляются и в более широком смысле). Иногда говорят, что приложение слушает канал, по кото- рому вещает другое приложение. Наконец, существуют такие термины, как клиент и сервер, однако они настолько устарели, что их употребление в данном контексте может считаться дурным тоном. Иногда употребление того или иного термина может показаться некорректным. Так, в рамках архитектуры Web-служб приложение, отправляющее сообщение с запросом поставщику службы, называется потребителем. К счастью, применение термина по- требитель в данном контексте ограничивается сценариями удаленного вызова процеду- ры (Remote Procedure Invocation, с. 85). В целом же приложение, которое отправляет или принимает сообщения, можно назвать клиентом системы обмена сообщениями или конечной точкой сообщения. Зачастую разработчики интеграционного решения неверно интерпретируют задачу создания канала сообщений. Как правило, разработчик создает код Java, вызывающий метод JMS API createQueue, или код .NET, включающий в себя выражение new MessageQueue, однако ни тот, ни другой не выделяет ресурсы для новой очереди в сис- теме обмена сообщениями. В действительности подобный код создает экземпляр объек- та, предоставляющего доступ к ресурсу, который был заранее предусмотрен администра- тором системы обмена сообщениями. Планируя каналы сообщений интеграционного решения, следует помнить, что каж- дый канал отнимает определенный объем оперативной или дисковой памяти. Любая реа- лизация системы обмена сообщениями предполагает наличие жесткого лимита поддер- живаемых каналов сообщений. Если разрабатываемое вами интеграционное решение требует тысяч каналов сообщений, обратите внимание на систему обмена сообщениями, обладающую незаурядной способностью к масштабированию.
Канал сообщений (Message Channel) 95 Имена каналов сообщений Поскольку каналы являются логическими адресами, они должны иметь некоторую форму записи. В большинстве случаев для обращения к каналу сообщений использу- ется буквенно-цифровое имя, такое как MyChannel. Некоторые системы обмена со- общениями поддерживают иерархические имена каналов, например MyCorp/Prod/ OrderProcessing/NewOrders. Все каналы сообщений делятся на два типа: каналы “точка-точка” (Point-to-Point Channel, с. 131) и каналы “публикация-подписка” (Publish-Subscribe Channel, с. 134). Поскольку передача разнородной информации по одному и тому же каналу может при- вести к возникновению непредвиденных ситуаций, рекомендуется использовать не- сколько каналов типа данных (Datatype Channel, с. 139) или реализовать функциональ- ность избирательного потребителя (Selective Consumer, с. 528). Кроме того, для каждого приложения рекомендуется предусмотреть канал недопустимых сообщений (Invalid Message Channel, с. 143), в который будут помещаться сообщения, не соответствующие опреде- ленным правилам. Приложение, не имеющее доступа к клиенту обмена сообщениями (Messaging, с. 87), можно подключить к системе обмена сообщениями с помощью адап- теров канала (Channel Adapter, с. 154). Набор каналов сообщений формирует шину сообще- ний (Message Bus, с. 162) для интегрируемых приложений. Пример: торговля на бирже Инициатор сделки помещает сообщение с запросом в соответствующий канал сообщений. Приложение, обрабатывающее запросы о сделках, считывает это сообщение из того же канала. Если запрашиваемому приложению нужно узнать текущие котировки, оно помещает сообщение с запросом в другой канал сообщений, специально предназначенный для получения информации данного типа. Пример: эталонная реализация службы J2EE JMS Набор инструментальных средств разработки (SDK) J2EE поставляется с эталонными реализациями служб J2EE, включая службу JMS. Для запуска эталонного сервера пред- назначена команда j 2ее, а для настройки каналов сообщений—средство j 2eeadmin: j2eeadmin -addJmsDestination jms/mytopic topic j2eeadmin -addJmsDestination jms/myqueue queue Как только администратор создаст каналы сообщений, к ним можно будет осуществ- лять доступ из клиентского кода JMS: Context jndiContext = new Initialcontext О; Queue myQueue = (Queue) jndiContext.lookup("jms/myqueue"); Topic myTopic = (Topic) jndiContext.lookup("jms/mytopic"); Запрос к службе JNDI не создает очередь или тему, поскольку они были созданы ранее с помощью команды j2eeadmin. Вместо этого JNDI-запрос создает экземпляр объекта Queue, который предоставляет доступ к очереди в системе обмена сообщениями.
96 Глава 3. Системы обмена сообщениями Пример: IBM WebSphere MQ Следующее выражение создает точку назначения (очередь myQueue) в системе обмена сообщениями, основанной на использовании связующего ПО IBM WebSphere MQ: DEFINE Q(myQueue) Поскольку WebSphere MQ (без полнофункционального сервера WebSphere Application Server) не содержит реализации службы JND1, мы не можем использовать ее для доступа к очереди сообщений. В этой ситуации доступ к очереди сообщений реализуется через JMS-сеанс, как показано ниже: Session session = // Создание сеанса. Queue queue = session.createQueue("myQueue"); Пример: Microsoft MSMQ Связующее ПО Microsoft MSMQ предоставляет несколько различных способов создания канала сообщений (очереди). В частности, для создания очереди можно воспользоваться средством Microsoft Message Queue Explorer или консолью Computer Management, как показано на рис. 3.3. Рис. 3.3. Консоль Computer Management позволяет создавать, настраивать и удалять очереди сообщений
Канал сообщений (Message Channel) 97 Ниже приведен пример создания очереди сообщений с помощью программного кода: using System.Messaging; MessageQueue.Create("MyQueue"); Для доступа к очереди сообщений приложение должно создать экземпляр объекта MessageQueue: MessageQueue mq = new MessageQueue("MyQueue");
98 Глава 3. Системы обмена сообщениями Сообщение (Message) Приложения, соединенные посредством канала сообщений (Message Channel, с. 93), взаимодействуют с помощью технологии обмена сообщениями (Messaging, с. 87). Как наладить обмен данными между двумя приложениями, соединенными с по- мощью канала сообщений (Message Channel)? Зачастую наличие канала сообщений воспринимается как достаточное условие для об- мена данными между двумя приложениями. Однако, в отличие от непрерывного потока информации, данные большинства приложений состоят из различных элементов, таких как записи, объекты, строки таблицы базы данных и т.п. Следовательно, канал сообще- ний должен обладать возможностью передачи разнородных элементов данных. Что же представляет собой процесс “передачи” информации? К примеру, передача параметра функции осуществляется посредством передачи указателя на адрес этого па- раметра в памяти. Подобным образом два потока, разделяющих одну область памяти, могут обмениваться указателями на записи или объекты. Поскольку двум различным процессам соответствуют отдельные области памяти, обмен информацией между процессами возможен только за счет копирования данных из одной области памяти в другую. Обычно для передачи данных используется поток бай- тов. Это означает, что первый процесс должен упорядочить данные в поток байтов и с копировать его во второй процесс. В свою очередь, второй процесс разупорядочить дан- ные в их исходное состояние. Механизм упорядочивания используется технологией уда- ленного вызова процедуры (Remote Procedure Call— RPC) для передачи параметров удаленному процессу и возврата результата. Таким образом, технология обмена сообщениями подразумевает передачу дискрет- ных элементов данных путем их упорядочения отправителем и разупорядочения получате- лем. Чтобы обеспечить возможность передачи разнородной информации, необходимо предусмотреть общий формат данных, передаваемых по каналу сообщений. Для передачи информации между двумя приложениями используйте формат сообщения (Message)— наименьшей единицы данных, которая может быть пе- редана системой обмена сообщениями по каналу сообщений (Message Channel, с. 93). Отправитель Сообщение Получатель
Сообщение (Message) 99 Следовательно, для передачи по каналам системы обмена сообщениями данные должны быть преобразованы в одно или несколько сообщений. Сообщение состоит из двух основных частей. 1. Заголовок сообщения. Информация, которая используется системой обмена сообщениями для описания передаваемых данных, включая адрес отправителя, адрес получателя и т.п. 2. Тело сообщения. Данные, передаваемые внутри сообщения и, как правило, игно- рируемые системой обмена сообщениями. Представленная выше концепция отнюдь не нова. Передача информации в виде дис- кретных сообщений применяется как традиционной почтовой службой, так и системой электронной почты. В сетях Ethernet данные передаются в виде кадров, а в Интернете— в виде пакетов TCP/IP. С точки зрения системы обмена сообщениями все сообщения одинаковы: тело каж- дого из них содержит данные, которые нужно передать в соответствии с информацией, размещающейся в заголовке. Однако, с точки зрения разработчика интеграционного решения, существуют разные типы сообщений, которые отличаются способом их ис- пользования. Так, для удаленного вызова процедуры применяется сообщение с командой (Command Message, с. 169), для передачи информации— сообщение с данными документа (Document Message, с. 171), а для уведомления получателя сообщения об изменении состояния отправителя— сообщение о событии (Event Message, с. 174). Если удаленное приложение должно ответить на полученное сообщение, используйте модель запрос- ответ (Request-Reply, с. 177). Если приложению необходимо передать информацию, размер которой превышает максимально допустимый размер сообщения, разбейте ее на меньшие части и отправьте в виде цепочки сообщений (Message Sequence, с. 192). Если передаваемая информация акту- альна только в течение ограниченного промежутка времени, отметьте эту особенность, указав срок действия сообщения (Message Expiration, с. 198). Поскольку все отправители и получатели сообщений должны использовать один и тот же формат данных, задайте его с помощью канонической модели данных (Canonical Data Model, с. 367). Пример: сообщение JMS Сообщение JMS представлено типом Message, имеющим несколько различных под- типов. 1. TextMessage. Наиболее распространенный тип сообщения. Тело сообщения представлено строкой (тип string), такой как простой текст или XML-документ. Для работы с телом сообщения используйте метод textMessage. getText (). 2. BytesMessage. Универсальный тип сообщения. Тело сообщения представлено байтовым массивом. Для копирования тела сообщения в указанный массив используйте метод bytesMessage. readBytes (byteArray). 3. Obj ectMessage. Тело сообщения представлено объектом Java, реализующим интерфейс java.io.Serializable. Для работы с телом сообщения (тип Serializable) используйте метод objectMes sage, getobj ect О .
100 Глава 3. Системы обмена сообщениями 4. streamMessage. Тело сообщения представлено потоком данных одного из при- митивных типов Java. Для работы с телом сообщения используйте методы readBoolean(), readchar(), readDouble() и т.п. 5. MapMessage. Тело сообщения представлено картой типа java.util .Map со строковыми (string) ключами. Для работы с телом сообщения используйте методы getBoolean("isEnabled"), getlnt("numberOfItems") и т.п. Пример: сообщение .NET Сообщение .NET представлено типом Message. Доступ к телу сообщения осуществляет- ся посредством свойства Body (тип Ob j ect), а также свойства ByteStream (тип Stream). Тип данных, хранящихся в теле сообщения (строка, дата, валюта, число и др.), определя- ется свойством BodyType. Пример: сообщение SOAP Сообщение протокола SOAP версии 1.1 представлено XML-конвертом (корневой эле- мент SOAP-ENV:Envelope), содержащим необязательный заголовок (элемент SOAP- ENV:Header) и обязательное тело (элемент soap-ENV: Body). Поскольку этот XML-документ является наименьшей единицей передачи данных (как правило, для пе- редачи SOAP-сообщений используется протокол HTTP), он является ни чем иным, как сообщением (Message). Ниже приведен типичный пример SOAP-сообщения, содержащего заголовок и тело. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <SOAP-ENV:Header > <t:Transaction xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1"> 5 </t: Transaction </SOAP-ENV:Header > <SOAP-ENV:Body> <m:GetLastTradePrice xmlns:m="Some-URI"> < symbol>DEF</symbol> </m:GetLastTradePrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope> SOAP позволяет продемонстрировать рекурсивную природу сообщений. Действитель- но, поскольку SOAP-сообщение может быть передано с помощью системы обмена сообще- ниями, это означает, что сообщение системы обмена сообщениями (например, объект JMS типа javax. jms .Message или объект .NET System.Messaging.Message) будет содер- жать в себе SOAP-сообщение (данные XML-документа soap-ENV:Envelope). В этом слу- чае транспортным протоколом SOAP-сообщения будет являться не HTTP, а внутренний
Сообщение (Message) 101 протокол передачи данных системы обмена сообщениями (в свою очередь, внутренний протокол системы обмена сообщениями может быть основан на использовании протокола HTTP с дополнительными средствами обеспечения надежной доставки данных). Передаче сообщения между различными системами обмена сообщениями посвящен шаблон проек- тирования оболочка конверта (Envelope Wrapper, с. 342).
102 Глава 3. Системы обмена сообщениями Каналы и фильтры (Pipes and Filters) Во многих интеграционных сценариях единственное событие может инициировать целую серию этапов обработки. Предположим, что сообщение о размещении нового за- каза должно передаваться в зашифрованном виде и нести в себе аутентификационную информацию в форме цифрового сертификата. Кроме того, необходимо предусмотреть защиту от дублирования сообщений. Учитывая вышеперечисленные требования, задача первичной обработки сообщений о размещении нового заказа сводится к преобразова- нию последовательности зашифрованных сообщений, включающих аутентификацион- ную информацию, с повторами в последовательность простых текстовых сообщений, не содержащих избыточных полей данных, без повторов. Как организовать сложную обработку сообщения, руководствуясь принципами независимости и гибкости конечного решения? Одно из возможных решений заключается в создании модуля обработки входящих сообщений, выполняющего все необходимые преобразования. Однако подобный подход не удовлетворяет требованию гибкости и усложняет тестирование. К примеру, нам может понадобиться добавить или удалить определенный этап обработки для сообщений о за- казах, размещенных крупными клиентами. Реализация всех функций в одном компоненте снижает возможность его повторного использования. Напротив, создание небольших, узкоспециализированных компонентов существенно повышает гибкость решения. Например, обработка сообшений о проверке состояния заказа требует их расшифровки, однако не требует реализации зашиты от дуб- лирования. Следовательно, вынесение функции расшифровки в отдельный модуль по- зволит применять его для обработки сообшений различных типов. Как правило, интеграционные решения используются для объединения нескольких гетерогенных систем. Это может привести к тому, что различные этапы обработки сооб- щения будут выполняться на разных физических устройствах. К примеру, закрытый ключ, который необходим для расшифровки входящих сообщений, по соображениям безопасности может быть доступен только для определенного компьютера. Подобным образом различные этапы обработки сообщения могут быть реализованы с помощью разных языков программирования или технологий, что будет являться препятствием для их совместного выполнения в рамках одного процесса. Реализация каждой функции в виде отдельного компонента еще не гарантирует их неза- висимость (к примеру, компонент расшифровки может использовать функциональность компонента аутентификации). Чтобы устранить связи между компонентами, этапы слож- ной обработки сообщения следует расположить в такой последовательности, которая бы исключала зависимость одного компонента от другого. Кроме того, все компоненты долж- ны иметь универсальный внешний интерфейс, допускающий их взаимозаменяемость. Взаимодействие между компонентами рекомендуется реализовать с помощью асин- хронного обмена сообщениями. В этом случае компонент сможет отправить сообщение другому компоненту, не дожидаясь от него ответа. Использование асинхронного обмена сообщениями позволит организовать одновременную обработку нескольких сообщений, по одному на каждый компонент.
Каналы и фильтры (Pipes and Filters) 103 Используйте архитектуру каналов и фильтров (Pipes and Filters) для разделения сложной вычислительной задачи на последовательность простых, независимых этапов (фильтров), объединенных с помощью каналов. Канал Расшифровка Входящий заказ Канал Канал Фильтр Аутентификация Защита от дублирования Канал Заказ в формате простого текста Фильтр Фильтр Каждый фильтр имеет очень простой интерфейс: он получает сообщение по входя- щему каналу, обрабатывает его и публикует полученный результат в исходящем канале. Канал соединяет два фильтра и используется для передачи сообщений. Поскольку все компоненты обладают одинаковыми внешними интерфейсами, их можно комбиниро- вать путем подключения к различным каналам. Можно добавлять новые фильтры, уда- лять или переупорядочивать существующие— и все это без необходимости внесения из- менений в сами фильтры. Соединение между фильтром и каналом часто называют пор- том. Простой фильтр имеет один входящий и один исходящий порт. Решение рассматриваемой нами задачи первичной обработки сообщений о размеще- нии нового заказа с помощью архитектуры каналов и фильтров предполагает применение трех фильтров и двух соединяющих эти фильтры каналов. Кроме того, нам понадобится один дополнительный канал для передачи исходного сообщения компоненту расшиф- ровки и один канал для передачи обработанного (текстового) сообщения системе управ- ления заказами. Архитектура каналов и фильтров является фундаментальной для систем обмена сооб- щениями: отдельные этапы обработки (фильтры) соединяются посредством каналов со- общений. На этой архитектуре основано множество шаблонов проектирования, рассмат- ривающихся в книге (например, шаблоны маршрутизации и преобразования). К тому же архитектура каналов и фильтров описывает универсальный способ объединения отдель- ных шаблонов проектирования в более сложные решения. Канал в архитектуре каналы и фильтры— это абстрактная сущность, соединяющая компоненты и одновременно отделяющая их друг от друга. Канал позволяет компоненту отправить сообщение для его последующего получения другим (неизвестным для отпра- вителя) компонентом. Очевидно, что канал в архитектуре каналы и фильтры может быть представлен каналом сообщений (Message Channel, с. 93). Благодаря независимости канала сообщений от языка программирования, а также аппаратной или программной платфор- мы этапы обработки (фильтры) могут быть распределены между различными компьюте- рами по соображениям безопасности, производительности, поддержки и др. Если же все компоненты удается разместить на одном компьютере, следует подумать о более эффек- тивной реализации каналов, такой как очередь в памяти. Таким образом, при проектиро- вании компонентов рекомендуется воздерживаться от конкретной реализации интерфей- са канала. Более подробно этот подход описывается шаблоном проектирования шлюз об- мена сообщениями (Messaging Gateway, с. 482).
104 Глава 3. Системы обмена сообщениями Один из недостатков архитектуры каналов и фильтров заключается в использовании большого числа каналов. Следует помнить, что реализация канала предполагает расходо- вание ресурсов памяти и процессора. К тому же публикация сообщения в канале требует преобразования данных из внутреннего формата отправителя в формат инфраструктуры обмена сообщениями (при получении сообщения выполняется обратная процедура). Та- ким образом, наличие длинной цепочки фильтров может привести к существенному снижению производительности вследствие многократного преобразования формата дан- ных сообщения. В чистом виде архитектура каналов и фильтров предполагает наличие у каждого фильтра одного входящего и одного исходящего порта. Специфика обмена сообщениями (Messaging, с. 87) требует пересмотра этого условия. В частности, компонент может из- влекать сообщения из более чем одного канала и помещать сообщения в более чем один канал (примером подобного компонента является маршрутизатор сообщений (Message Router, с. 109)). Кроме того, несколько фильтров могут считывать сообщения из одного и того же канала сообщений. Если же сообщение предназначено единственному получате- лю, для его передачи применяется канал “точка-точка” (Point-to-Point Channel, с. 131). Применение архитектуры каналов и фильтров позволяет тестировать отдельные компо- ненты с помощью тестового сообщения (Test Message, с. 577). Тестирование и отладка базо- вых функций решения гораздо эффективнее, нежели тестирование всего решения целиком. К примеру, для тестирования функций шифрования и расшифровки данных следует сгене- рировать большое количество сообщений с произвольным содержимым, передать их для последовательной обработки компонентам шифрования и расшифровки, а затем сравнить полученный результат с исходными сообщениями. Подобным образом для тестирования функции аутентификации следует сгенерировать сообщения с заранее известными кодами аутентификации и передать их на обработку соответствующему компоненту. Конвейерная обработка Объединение компонентов с помощью асинхронных каналов сообщений (Message Channel, с. 93) позволяет каждому из них выполняться в собственном потоке или процес- се. Это означает, что, завершив обработку сообщения и поместив его в исходящий канал, компонент может приступить к обработке нового сообщения, не дожидаясь подтвержде- ния о получении сообщения следующим компонентом в цепочке. Подобный подход по- зволяет обрабатывать несколько сообщений одновременно, как показано на рис. 3.4. По сравнению с последовательной обработкой сообщений конвейерная обработка существенно повышает пропускную способность системы. Параллельная обработка Пропускная способность системы ограничена пропускной способностью ее самого мед- ленного процесса. Увеличение пропускной способности процесса возможно за счет созда- ния его нескольких параллельно выполняющихся экземпляров. Гарантия получения сооб- щения ровно одним из N доступных обработчиков обеспечивается сочетанием канала “точка-точка” (Point-to-Point Channel, с. 131) и конкурирующих потребителей (Competing Consumers, с. 515). Следует отметить, что подобный способ увеличения производительности системы может привести к нарушению порядка обработки сообщений. Если порядок со- общений имеет значение, нужно ограничиться только одним экземпляром каждого компо- нента или воспользоваться преобразователем порядка (Resequencer, с. 297).
Каналы и фильтры (Pipes and Filters) 105 Сообщение 1 Сообщение 2 Сообщение 3 Последова- тельная обработка Расшиф- ровка Аутенти- фикация Защита от дублиро- вания Расшиф- Аутенти- Защита от ровка фикация дублиро- DSi-lua Расшиф- ровка Аутенти- Защита от фикация дублиро- вания Врамя Конвейерная обработка Расшиф- ровка Аутенти- фикация Расшиф- ровка Защита от дублиро- вания Сообщение 1 Аутенти- фикация Защита от дублиро- вания^ Сообщение 2 Расшиф- Аутенти- Защита от ровка фикация дублиро- Сообщение 3 Врамя Рис. 3.4. Конвейерная обработка сообщений с помощью архитектуры каналов и фильтров (Pipes and Filters) Предположим, что на расшифровку сообщения уходит гораздо больше времени, чем на его аутентификацию. Чтобы ускорить обработку сообщения, создадим два дополни- тельных экземпляра компонента расшифровки, как показано на рис. 3.5. заказ Рис. 3.5. Повышение пропускной способности системы за счет параллельной обработки сообщений Заказ в формате простого текста Использование параллельно выполняющихся экземпляров фильтра наиболее эффек- тивно, если фильтр не сохраняет свое состояние, т.е. возвращается к исходному состоя- нию после обработки сообщения. Примером фильтра, сохраняющего состояние, являет- ся компонент, реализующий защиту от дублирования сообшений. История архитектуры каналов и фильтров Простота и эффективность каналов и фильтров (Pipes and Filters) завоевала этой архи- тектуре огромную популярность, а несложная семантика позволила описать ее формаль- ными методами.
106 Глава 3. Системы обмена сообщениями В 1974 году Кан определил вычислительную сеть Кана как набор параллельных про- цессов, объединенных неограниченными каналами FIFO (First-In, First-Out— первым прибыл, первым обслужен) [19]. В [11] есть глава, в которой описываются различные ар- хитектурные стили, включая каналы и фильтры. Монро дает подробное толкование взаи- моотношения между архитектурными стилями и шаблонами проектирования в [26]. Статья Режин Менье “The Pipes and Filters Architecture” (“Архитектура каналов и фильт- ров”), опубликованная в [31], послужила основой для шаблона проектирования каналы и фильтры (Pipes and Filters), включенного в [33]. Практически все реализации каналов и фильтров соответствуют представленной в [33] схеме “Scenario IV” (“Сценарий IV”), которая подразумевает наличие активных фильтров, независимо друг от друга считы- вающих, обрабатывающих и помещающих элементы в каналы. Шаблон, описанный в [33], предполагает, что каждый элемент проходит одинаковые этапы обработки при пе- редаче от фильтра к фильтру. Это условие неизбежно нарушается, когда речь заходит о сценариях интеграции. В большинстве случаев маршрут сообщения определяется дина- мически на основе содержимого сообщения или административным путем. В действи- тельности маршрутизация сообщений является настолько обыденной практикой в ин- теграции корпоративных приложений, что для ее описания предусмотрен отдельный шаблон проектирования маршрутизатор сообщений (Message Router, с. 109). Словарь Обсуждая архитектуру каналов и фильтров (Pipes and Filters), следует обратить внима- ние на корректность употребления термина фильтр. Позднее нами будут рассмотрены такие шаблоны проектирования, как фильтр сообщений (Message Filter, с. 253) и фильтр содержимого (Content Filter, с. 354). Следует отметить, что это далеко не единственные фильтры среди представленных в данной книге шаблонов. Дело в том, что фильтр в терминах архитектуры фильтров и каналов совсем не обязательно должен реализовы- вать функцию отбора (полей или сообщений). Чтобы избежать недоразумения, мы могли бы переименовать архитектуру каналов и фильтров, что, однако же, способно привести к еще большей путанице. Употребляя термин фильтр, мы постараемся делать это так, чтобы читателю было понятно, о чем идет речь— о фильтре архитектуры ка- налов и фильтров или о шаблонах проектирования фильтр сообщений/фильтр содержи- мого. Если контекст, в котором будет упоминаться термин фильтр, не позволит сделать однозначного вывода, для обозначения фильтра архитектуры каналов и фильтров будет применяться термин компонент. Архитектура каналов и фильтров имеет сходство с концепцией CSP (Communicating Sequential Processes—взаимодействие последовательных процессов), впервые представ- ленной Хоаром в 1978 году [6]. Хоар предлагает использовать простую модель для описа- ния проблем синхронизации в системах параллельной обработки. Механизм, лежащий в основе CSP, применяется для синхронизации двух процессов посредством системы ввода-вывода. Взаимодействие между процессами осуществляется при условии готовно- сти процесса А к передаче информации процессу Б, а процесса Б— к принятию инфор- мации от процесса А. Если это условие выполняется только наполовину, один из процес- сов ставится в очередь ожидания готовности другого процесса. В отличие от интеграци- онных решений концепция CSP предполагает более сильное связывание процессов и
Каналы и фильтры (Pipes and Fitters) 107 отсутствие поддержки очередей “каналов”. Тем не менее знакомство с ней очень полезно при изучении архитектуры каналов и фильтров. Пример: простой фильтр MSMQ (С#) Ниже приведен код базового класса фильтра с одним входящим и одним исходящим пор- том. Функциональность класса Processor предельно проста: вывести тело полученного сообщения на консоль и отправить его через исходящий порт. Для реализации более полезной функциональности (например, преобразования формата содержимого сообще- ния или его перенаправления в другой порт) следует создать подкласс класса Processor, переопределяющий метод ProcessMessage. Обратите внимание, что экземпляр класса Processor получает ссылки на входящий и исходящий каналы на этапе своего создания. Таким образом, класс Processor не при- вязан к каким-либо конкретным каналам или фильтрам, что позволяет создавать несколько экземпляров фильтров и объединять их в произвольном порядке. using System; using System.Messaging; namespace PipesAndFiIters { public class Processor { protected MessageQueue inputQueue; protected MessageQueue outputQueue; public Processor (MessageQueue inputQueue, MessageQueue outputQueue) { this.inputQueue = inputQueue; this.outputQueue = outputQueue; } public void Process () { inputQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(OnReceiveCompleted); inputQueue.BeginReceive(); } private void OnReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult) { MessageQueue mq = (MessageQueue)source; Message inputMessage = mq.EndReceive(asyncResult.AsyncResult); inputMessage.Formatter = new XmlMessageFormatter (new String[] {"System.String,mscorlib"}); Message outputMessage = ProcessMessage(inputMessage); outputQueue.Send(outputMessage);
108 Глава 3. Системы обмена сообщениями mq.BeginReceive(); } protected virtual Message ProcessMessage(Message m) Console.WriteLine("Received Message: " + m.Body); return (m); Фильтр Processor является примером реализации событийно управляемого потребите- ля {Event-Driven Consumer, с. 511). Метод Process регистрируется для получения входящих сообщений и уведомляет систему обмена сообщениями о необходимости вызова метода OnReceiveCompleted при получении каждого сообщения. Метод OnReceiveCompleted извлекает данные из объекта события и вызывает виртуальный метод ProcessMessage. Представленный выше фильтр не является транзакционным. Если во время обработ- ки сообщения (до его помещения в исходящий канал) произойдет ошибка, сообщение будет потеряно. Решение данной проблемы описывается шаблоном проектирования транзакционный клиент {Transactional Client, с. 498).
Маршрутизатор сообщений (Message Router) 109 Маршрутизатор сообщений (Message Router) Несколько этапов обработки в цепочке каналов и фильтров (Pipes and Filters, с. 102) соединены с помощью каналов сообщений (Message Channel, с. 93). Как реализовать возможность передачи сообщения различным фильтрам в зави- симости от набора условий? Архитектура каналов и фильтров предусматривает непосредственное соединение фильтров друг с другом с помощью фиксированных каналов. Подобный подход вполне оправдан, поскольку в большинстве случаев шаблон каналы и фильтры применяется для обработки больших наборов однотипных данных [33]. К примеру, при компиляции про- граммного кода каждая его строка проходит три последовательных этапа обработки: лек- сический анализ, синтаксический анализ и семантический анализ. Сообщения, приме- няющиеся в интеграционных решениях, как правило, не связаны с каким-либо набором данных. В результате каждое сообщение может потребовать свою цепочку вычислений. Канал сообщений позволяет провести четкую границу между отправителем и получате- лем сообщения (Message, с. 98). В частности, из этого следует, что несколько приложений могут публиковать сообщения в одном и том же канале сообщений. В результате канал со- общений может содержать сообщения, способ обработки которых будет зависеть от их ти- па, источника или какого-либо другого критерия. Несмотря на то что для передачи со- общения каждого типа можно задействовать отдельный канал сообщений (более подробно эта концепция описывается шаблоном проектирования канал типа данных (Datatype Channel, с. 139)), это приведет к необходимости классификации сообщений отправите- лями, а также к существенному росту числа каналов сообщений. К тому же способ обра- ботки сообщения не всегда зависит от его источника. Представим ситуацию, в которой получатель сообщения определяется динамически на основе общего числа сообщений, переданных по конкретному каналу. Поскольку это число не может знать ни один из от- правителей, он не сможет выбрать корректный канал для размещения сообщения. Канал сообщений обеспечивает простую форму маршрутизации сообщений. Публикуя сообщение в канале сообщений, приложение теряет контроль за его доставкой. Отныне маршрут сообщения зависит от компонента, находящегося на другом конце канала сооб- щений. К сожалению, этот тип “маршрутизации” не учитывает свойства самого сообще- ния и напоминает использование символа “ | ” для обработки текстовых файлов в систе- мах UNIX. Подобно каналу сообщений символ “ | ” позволяет создать цепочку каналов и фильтров, однако на время ее существования все строки текстового файла будут прохо- дить одни и те же этапы обработки. Решение о необходимости обработки сообщения, поступившего по общему каналу со- общений, можно возложить на получателя. Однако как только сообщение будет извлечено из канала, оно перестанет быть доступным для проверки другим компонентам. Некото- рые системы обмена сообщениями позволяют просмотреть свойства сообщения без его извлечения из канала. Тем не менее это решение не является универсальным и к тому же “привязывает” компонент к определенному типу сообщения. Встраивание логики выбо-
110 Глава 3. Системы обмена сообщениями ра сообщения в компонент затрудняет его повторное использование и сводит на нет ос- новное преимущество модели каналов и фильтров— возможность переупорядочивания компонентов. Большинство альтернативных подходов предполагает внесение изменений в компо- ненты. Однако компоненты интеграционных решений— это, как правило, крупные приложения, модифицировать которые зачастую не представляется возможным. Следо- вательно, изменение отправителей или получателей сообщений для удовлетворения тре- бований системы обмена сообщениями не только экономически невыгодно, но и в большинстве случаев попросту невозможно. Как уже упоминалось, одним из преимуществ архитектуры каналов и фильтров явля- ется возможность переупорядочивания компонентов. В частности, это позволяет добав- лять дополнительные этапы (например, этап, реализующий логику маршрутизации) в цепочку фильтров, не затрагивая существующие компоненты. Добавьте специальный фильтр—маршрутизатор сообщений (Message Router),— который будет извлекать сообщение (Message, с. 98) из одного канала сообщений (Message Channel, с. 93) и размещать его в другом канале сообщений на основе заданного условия. Маршрутизатор сообщений не соответствует базовому определению архитектуры каналов и фильтров в том смысле, что он имеет несколько исходящих каналов (т.е. более одного исходящего порта). Вместе с тем особенность этой архитектуры позволяет скрыть существование маршрутизатора сообщений от соседних с ним компонентов— как и пре- жде, они извлекают сообщения из входящего канала, обрабатывают их и помещают в исходящий канал. Ключевое свойство маршрутизатора сообщений состоит в том, что он не изменяет содержимого сообщения, заботясь только о его корректной доставке. Использование маршрутизатора сообщений позволяет сосредоточить всю логику при- нятия решения о доставке сообщения в одном компоненте. Отныне определение новых типов сообщений, добавление новых этапов обработки или изменение правил маршрути- зации затронет только один компонент, а именно маршрутизатор сообщений. Кроме того, прохождение всех входящих сообщений через маршрутизатор сообщений делает возмож- ной их обработку в корректном порядке. К сожалению, маршрутизатору сообщений свойственны определенные недостатки. В частности, он должен обладать информацией обо всех доступных каналах сообщений. Если эти сведения часто меняются, маршрутизатор сообщений может превратиться в “узкое место” интеграционного решения. В этом случае рекомендуется переложить от-
Маршрутизатор сообщений (Message Router) 111 ветственность за выбор сообщения на получателя, воспользовавшись каналом “публикация-подписка” (Publish-Subscribe Channel, с. 134) и набором фильтров сообщений (Message Filter, с. 253). Метод, подразумевающий использование маршрутизатора сообще- ний, получил название предиктивная маршрутизация, а метод, возлагающий ответствен- ность за выбор сообщения на получателя, — реактивная фильтрация (более подробно сравнение двух подходов приводится в описании шаблона фильтр сообщений в главе 7). Поскольку использование маршрутизатора сообщений подразумевает добавление но- вого этапа обработки, это приводит к снижению производительности интеграционного решения. Чтобы минимизировать негативный эффект предиктивной маршрутизации, можно запустить несколько параллельных процессов маршрутизатора сообщений или ус- тановить дополнительное оборудование. Это позволит сохранить пропускную способ- ность системы (количество сообщений, обработанных за единицу времени) на прежнем уровне, однако практически неизбежно увеличит ее задержку (время, требующееся для передачи одного сообщения). Применение маршрутизаторов сообщений способно превратить преимущество слабо- связанной системы в ее недостаток. Зачастую слабая связь между компонентами реше- ния мешает отслеживанию потоков сообщений. Использование маршрутизаторов сооб- щений только усугубляет положение. Невозможность определения потока сообщений за- трудняет тестирование, отладку и поддержку интеграционного решения. Для устранения этой проблемы можно воспользоваться журналом доставки сообщения (Message History, с. 561), в который заносится информация о компонентах, через которые прошло сооб- щение. Альтернативный подход заключается в составлении списка всех каналов, к кото- рым подключены компоненты системы, что позволит создать граф допустимых потоков сообщений интеграционного решения. Многие средства интеграции корпоративных приложений (EAI) хранят подобную информацию в центральном репозитории, делая ее легко доступной для анализа. Типы маршрутизаторов сообщений Маршрутизатор сообщений (Message Router) может использовать несколько различных критериев при определении исходящего канала для отправки сообщения. Наиболее три- виальный пример маршрутизатора сообщений— это так называемый фиксированный маршрутизатор. Фиксированный маршрутизатор имеет один входящий и один исходя- щий канал. Функциональность фиксированного маршрутизатора предельно проста— извлечь сообщение из входящего канала и поместить его в исходящий канал. Зачем же нужен такой примитивный маршрутизатор? Во-первых, фиксированный маршрутизатор может использоваться как временное решение до реализации более интеллектуальной логики маршрутизации. Во-вторых, фиксированный маршрутизатор может применяться для перенаправления сообщений между несколькими интеграционными решениями. За- частую вместе с фиксированным маршрутизатором используются транслятор сообщений (Message Translator, с. 115) и адаптер канала (Channel Adapter, с. 154). Многие маршрутизаторы сообщений принимают решение о точке назначения сооб- щения на основании его свойств, например типа сообщения или значения определенных полей. Подобные маршрутизаторы получили название маршрутизаторы на основе содер- жимого (Content-Based Router, с. 247). Более подробно маршрутизатор на основе содержи- мого описывается соответствующим шаблоном проектирования.
112 Глава 3. Системы обмена сообщениями Оставшиеся маршрутизаторы сообщений принимают решение о точке назначения со- общения на основании условий среды. Подобные маршрутизаторы получили название маршрутизаторы на основе контекста. Как правило, маршрутизаторы на основе контекста применяются для балансировки нагрузки, тестирования или обеспечения восстановления при отказе. К примеру, если компонент выйдет из строя, маршрутизатор на основе контек- ста сможет перенаправить сообщения на обработку другим компонентом с аналогичной функциональностью. Некоторые маршрутизаторы на основе контекста разделяют поток сообщений между несколькими каналами для достижения эффекта балансировки нагрузки. Следует отметить, что возможность балансировки нагрузки можно реализовать и без ис- пользования маршрутизатора сообщений. В частности, примером балансировки нагрузки является извлечение сообщений несколькими конкурирующими потребителями (Competing Consumers, с. 515) из одного и того же канала сообщений (Message Channel, с. 93) для парал- лельной обработки. Несмотря на это применение маршрутизатора сообщений позволит реа- лизовать более интеллектуальную логику маршрутизации по сравнению с простой логикой алгоритма кругового обслуживания, реализуемой каналом сообщений. Многие маршрутизаторы сообщений являются маршрутизаторами без поддержки со- стояния. Другими словами, принятие решения о передаче сообщения принимается без учета ранее переданных сообщений. Маршрутизаторы, которые учитывают обработан- ные ранее сообщения при принятии решения о точке назначения текущего сообщения, называются маршрутизаторами с поддержкой состояния. Примером маршрутизатора с поддержкой состояния является компонент, реализующий защиту от дублирования со- общений из рассмотренного ранее примера использования архитектуры каналов и фильт- ров (Pipes and Filters, с. 102). В большинстве случаев логика маршрутизации жестко закодирована в маршрутиза- торе сообщений. Тем не менее некоторые маршрутизаторы могут принимать решение о перенаправлении сообщения на основе информации, полученной по шине управления (Control Bus, с. 552). Этот подход позволяет изменять критерий маршрутизации, не внося изменений в маршрутизатор и не затрагивая текущий поток сообщений. К примеру, шина управления может передать значение некоторой глобальной переменной всем маршрути- заторам сообщений в системе для перевода последней из тестового режима функциониро- вания в рабочий. Динамический маршрутизатор (Dynamic Router, с. 259) обладает способ- ностью к изменению логики маршрутизации на основании управляющих сообщений, полученных от конечных точек системы. Более подробно различные типы маршрутизаторов сообщений рассматриваются в главе 7. Пример: коммерческие средства EAI Концепция маршрутизатора сообщений (Message Router) является основой для брокера сооб- щений (Message Broker, с. 334)—средства, реализованного практически во всех EAI-пакетах. Брокер сообщений принимает входящие сообщения, тестирует их на предмет наличия оши- бок, преобразовывает и помещает в требуемый исходящий канал. Подобная архитектура позволяет максимально изолировать приложения друг от друга, что чрезвычайно важно для их интеграции. Брокер сообщений реализует всю логику, требующуюся для маршрутизации сообщений между приложениями, и, по сути, является “интеграционным” аналогом посредника (Mediator) [12].
Маршрутизатор сообщений (Message Router) 113 Пример: простой маршрутизатор MSMQ (С#) Следующий код демонстрирует пример реализации простого маршрутизатора, перенаправ- ляющего все входящие сообщения в один из двух каналов на основе заданного условия, class SimpleRouter { protected MessageQueue inQueue; protected MessageQueue outQueuel; protected MessageQueue outQueue2; public SimpleRouter(MessageQueue inQueue, MessageQueue outQueuel, MessageQueue outQueue2) { this.inQueue = inQueue; this.outQueuel = outQueuel; this.outQueue2 = outQueue2; inQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(OnMessage); inQueue.BeginReceive (); } private void OnMessage(Object source, ReceiveCompletedEventArgs asyncResult) { MessageQueue mq = (MessageQueue)source; Message message = mq.EndReceive(asyncResult.AsyncResult); if (IsConditionFulfilledO) outQueuel.Send(message); else outQueue2.Send(message); mq.BeginReceive(); } protected bool toggle = false; protected bool IsConditionFulfilled () { toggle = !toggle; return toggle; Подобно простому фильтру, представленному при описании архитектуры каналов и фильтров (Pipes and Filters, с. 102), класс SimpleRouter реализует событийно управляемый потребитель (Event-Driven Consumer, с. 511) сообщений с использованием делегатов. Кон- структор регистрирует метод OnMessage в качестве обработчика сообщений, поступаю- щих по каналу inQueue. Среда .NET будет вызывать метод OnMessage для обработки каждого сообщения, извлеченного из канала inQueue. Метод OnMessage определяет маршрут сообщения с помощью метода IsConditionFulf illed. В рассмотренном вы- ше примере метод IsConditionFulf illed реализует простую логику маршрутизации,
114 Глава 3. Системы обмена сообщениями поочередно помещая сообщения в каналы outQueuel и outQueue2. Маршрутизатор simp 1 eRouter не является транзакционным. Если во время обработки сообщения (до его помещения в исходящий канал) произойдет ошибка, сообщение будет потеряно. Решение данной проблемы описывается шаблоном проектирования транзакционный клиент (TransactionalClient, с. 498).
Транслятор сообщений (Message Translator) 115 Транслятор сообщений (Message Translator) Ранее мы рассмотрели шаблоны, касающиеся создания сообщений и их доставки получателю. Большинство интеграционных решений объединяет разнородные приложе- ния— унаследованные, коммерческие и созданные на заказ. Как правило, каждое из этих приложений использует собственную модель данных. К примеру, система бухгал- терского учета может оперировать такими данными о заказчике, как номер налогопла- тельщика, а система управления взаимоотношениями с клиентами (CRM) — телефон- ным номером и адресом проживания. Зачастую модель данных приложения является ос- новой для схемы базы данных, формата файлов и интерфейса API—точек “соприкосно- вения” приложения с интеграционным решением. Вдобавок к внутренним моделям данных приложений интеграционное решение должно поддерживать стандартные форматы данных, применяющиеся для взаимодейст- вия с внешними приложениями. Стандартные протоколы и форматы данных создаются различными консорциумами и комитетами по стандартизации, такими как RosettaNet, ebXML, OAGIS и др. В большинстве случаев “официальные” форматы данных исполь- зуются для взаимодействия интеграционного решения с приложениями бизнес - партнеров и внешних организаций. Как организовать обмен сообщениями между приложениями, использующими различные форматы данных? Если бы все интегрируемые приложения использовали одинаковые форматы данных, задача преобразования сообшений решилась бы сама собой. К сожалению, это очень сложно реализовать по целому ряду причин (см. шаблон проектирования общая база дан- ных (Shared Database, с. 83)). Во-первых, изменение внутреннего формата данных требует внесения большого объема изменений в бизнес-логику приложения, что экономически нецелесообразно для большинства унаследованных приложений (вспомним попытку из- менения единственного поля в рамках “проблемы 2000”). Во-вторых, использование одинаковых имен полей и, возможно, типов данных может сочетаться с различным представлением информации, к примеру XML-документ и файл данных COBOL. В-третьих, приведение формата данных одного приложения к формату данных дру- гого приложения приводит к их сильному связыванию. Как известно, одним из ключе- вых принципов проектирования интеграционных решений является слабая связь между объединяемыми приложениями (см. шаблон проектирования каноническая модель данных (Canonical Data Model, с. 367)). Идентичность форматов данных приложений нарушает этот принцип. Отныне замена приложения или внесение в него изменений (сценарий, присущий интеграционным решениям) будет иметь существенные последствия для ос- тальных приложений. Функция преобразования формата данных может быть встроена в конечную точку со- общения (Message Endpoint, с. 124). В результате все приложения будут отправлять и при- нимать сообщения общего формата данных. Однако этот подход предполагает наличие
116 Глава 3. Системы обмена сообщениями доступа к исходному коду конечной точки, что возможно далеко не всегда. К тому же встраивание кода преобразования в конечную точку снижает возможность его повтор- ного использования. Используйте для преобразования формата данных специальный фильтр— транслятор сообщений (Message Translator},— расположив его между другими фильтрами или приложениями. Входящее сообщение Сообщение после преобразования Транслятор сообщений (Message Translator}— эквивалент шаблона проектирования адаптер (Adapter), описанного в [12]. Адаптер преобразует интерфейс компонента в дру- гой интерфейс, который может быть использован в отличном контексте. Уровни преобразования Преобразование сообщений может осуществляться на нескольких различных уров- нях. К примеру, элементы данных приложений могут иметь одни и те же имя и тип, од- нако отличаться представлением (ХМ L-документ, файл с разделителями-запятыми и т.д.). С другой стороны, элементы данных могут иметь одинаковые форматы (например, XML), однако отличаться именами. Обобщим различные типы преобразования сообще- ний, разделив их на несколько уровней (табл. 3.1). Таблица 3.1. Уровни преобразования сообщений Уровень Объект преобразования Пример Средства/методы Структуры данных (приложения) Типа данных Сущность, ассоциация, кардинальность Имя поля, тип данных, область определения значения, ограничение, значение кода Приведение отношения “множество-множество” к агрегации Преобразование почтового индекса из числа в строку; объединение полей First Name и Last Name в поле Name; замена названия штата США двузначным кодом Шаблоны структурного преобразования, заказной код Визуальные редакторы преобразования EAI, XSL, обращение к базе данных, заказной код
Транслятор сообщений (Message Translator) 117 Окончание табл. 3.1 Уровень Объект преобразования Пример Средства/методы Представления данных Формат данных (XML, пары “имя-значение”, поля данных фиксированной длины, форматы EAI-вендоров и др.), набор символов (ASCII, Unicode, EBCDIC), шифрование/сжатие Анализ представления данных с последующим преобразованием в другой формат; шифрование/расшифровка данных Анализаторы XML, анализаторы/генераторы EAI, заказные API Транспортный Коммуникационные протоколы: сокеты TCP/IP, HTTP, SOAP, JMS, TIBCO Rendezvous Передача данных с использованием одного из коммуникационных протоколов без изменения содержимого сообщения Адаптер канала (Channel Adapter, с. 154), адаптеры ЕА1 Транспортный уровень обеспечивает передачу данных между различными системами. На этом уровне осуществляется надежный обмен данными между сетевыми сегментами, включающий исправление ошибок. Некоторые EAl-вендоры разрабатывают собствен- ные транспортные протоколы (например, TIBCO Rendezvous), в то время как остальные технологии интеграции основываются на использовании протоколов TCP/IP (например, SOAP). Преобразование сообщений между различными транспортными уровням можно реализовать с помощью адаптера канала (Channel Adapter, с. 154). Уровень представления данных часто называют уровнем синтаксиса. Как следует из его названия, этот уровень определяет представление передаваемых данных. Поскольку на транспортном уровне осуществляется передача потока символов или байтов, сложные структуры данных должны быть преобразованы в строку с помощью одного из распро- страненных форматов—XML, полей фиксированной длины (например, записей EDI) и др. Во многих случаях данные сжимаются и (или) шифруются, в результате чего к ним добавляется дополнительная информация, такая как контрольная сумма или цифровой сертификат. Объединение систем, использующих различные представления данных, за- частую предполагает расшифровку, распаковку и анализ данных с последующим созда- нием нового представления, сжатием и шифрованием (при необходимости). Уровень типа данных определяет типы данных, на которых основана модель прило- жения. На этом уровне принимаются такие решения, как способ представления полей даты (строка или специальная структура), формат почтового индекса и т.п. Большинство подобных решений фиксируется в так называемом словаре данных. Иногда вопросы, ка- сающиеся типов данных, выходят за пределы выбора между строковым и числовым пред- ставлениями значения. Предположим, что информация о продажах товаров сгруппиро- вана по регионам. Приложение, установленное в отделе продаж, разделяет страну на че- тыре региона—Запад, Центр, Юг и Восток,—для представления которых используются буквы “3”, “Ц”, “Ю” и “В” соответственно. В то же время приложение, установленное в отделе маркетинга, выделяет три дополнительных региона— Тихоокеанский, Северо- Восточный и Юго-Восточный,— используя для представления регионов двузначные числа. Какое число следует поставить в соответствие букве “В”?
118 Глава 3. Системы обмена сообщениями Уровень структуры данных описывает данные с точки зрения модели домена прило- жения (именно поэтому его вторым названием является уровень приложения). Этот уро- вень определяет логические сущности, которыми оперирует приложение (например, “заказчик”, “адрес” или “счет”), а также взаимоотношения между ними (может ли один заказчик иметь несколько счетов (адресов), могут ли несколько заказчиков иметь одина- ковые адреса (счета), частью какой сущности (счета или заказчика) является адрес и т.д.). Зачастую на уровне структуры данных используются диаграммы сущностей и связей, а также классовые диаграммы. Уровни связывания Многие компромиссные решения, принимаемые при интеграции приложений, свя- заны с необходимостью уменьшения зависимости между объединяемыми системами. Слабое связывание интегрированных приложений создает основу для эффективного управления изменениями. Благодаря каналам сообщений (Message Channel, с. 93) прило- жения могут не знать расположение друг друга. Маршрутизатор сообщений (Message Router, с. 109) избавляет приложения от необходимости иметь общий канал сообщений. Несмотря на это приложения могут все еще сильно зависеть друг от друга по причине связанности внутренних форматов данных. Именно этот уровень связывания и призван устранить транслятор сообщений (Message Translator, с. 115). Цепочечные преобразования Многие сценарии бизнес-интеграции предполагают преобразование данных на не- скольких различных уровнях. Предположим, что запись заказа покупок EDI 850, пред- ставленную файлом с фиксированным форматом, следует преобразовать в XML- документ и отправить по протоколу HTTP в систему управления заказами, использую- щую отличное определение объекта Order. Необходимые при этом преобразования охва- тывают все четыре уровня: преобразование способа транспортировки данных с передачи файла на передачу по протоколу HTTP; преобразование представления данных с файла фиксированного формата в документ XML; а также преобразование типа и структуры данных в соответствии с определением объекта Order системы управления заказами. Преимущество рассмотренной ранее модели многоуровневого преобразования состоит в независимости каждого уровня от остальных уровней, как показано на рис. 3.6. Программа А Уровень структуры данных I ”УровёньттаданныТ”-~ Уровень представления данных Программа Б Транспортный уровень Рис. 3.6. Взаимоотношения между уровнями преобразования
Транслятор сообщений (Message Translator) 119 На рис. 3.7 показан результат объединения нескольких трансляторов сообщений (Message Translator) с помощью архитектуры каналов и фильтров (Pipes and Filters, с. 102). Создание одного транслятора сообщений для каждого уровня преобразования позво- ляет использовать этот компонент в других сценариях интеграции. К примеру, адаптер канала (Channel Adapter, с. 154) и транслятор сообщений EDI-B-XML представляют собой универсальное сочетание компонентов, которое можно применять при обработке любых входящих документов EDL Адаптер канала EDI-B-XML 850-в-Сообщение о размещении заказа Система управления заказами Сообщение о размещении заказа Рис. 3.7. Соединение в цепочку нескольких трансляторов сообщений (Message Translator) Объединение нескольких трансляторов сообщений в цепочку позволяет при необхо- димости вносить изменения в ее звенья без затрагивания оставшихся компонентов. К примеру, замена функции преобразования в файл фиксированного формата функцией преобразования в файл с разделителями-запятыми сводится к замене компонента на со- ответствующем уровне преобразования. Существует несколько различных разновидностей трансляторов сообщений. Оболочка конверта (Envelope Wrapper, с. 342) предусматривает помещение данных сообщения в “конверт” для последующей передачи через систему обмена сообщениями. Расширитель содержимого (Content Enricher, с. 348) добавляет информацию в сообщение, а фильтр со- держимого (Content Filter, с. 354) удаляет ее. Шаблон проектирования квитанция (Claim Check, с. 358) предполагает удаление информации для ее последующего извлечения. Нор- мализатор (Normalizer, с. 364) преобразует несколько различных форматов сообщений в общий формат. Наконец, каноническая модель данных (Canonical Data Model, с. 367) де- монстрирует пример совместного использования нескольких трансляторов сообщений для устранения различий между внутренними форматами данных объединяемых прило- жений. Каждый из перечисленных шаблонов проектирования реализует сложные струк- турные преобразования, такие как отображение взаимоотношения “множество- множество” на взаимоотношение “один-к-одному”. Пример: структурные преобразования XSL Консорциум W3C определил стандартный язык преобразования XML-документов— Extensible Stylesheet Language (расширяемый язык стилей, XSL). Частью XSL является основанный на правилах язык XSL Transformation (преобразование XSL, XSLT), исполь- зующийся для преобразования формата документа XML. Рассмотрим конкретный при- мер, демонстрирующий использование языков XSL и XSLT (более подробно язык XSLT описывается в [40, 49]).
120 Глава 3. Системы обмена сообщениями Рассмотрим задачу передачи входящего XML-документа в систему бухгалтерского учета. При отсутствии отличий на уровне представления данных (XML) остается устра- нить рассогласование имен полей, типов данных и их структуры. Исходный XML- документ показан ниже. <data> <customer> <firstname>Joe</firstname> <lastname >Doe</lastname> <address type="primary"> <ref id="55355"/> </address> <address type="secondary"> <ref id="77889"/> </address> </customer> <address id="55355"> <street>123 Main</street> <city>San Francisco</city> <state>CA</state> <postalcode>94123</postalcode> <country>USA</country> <phone type="cell"> <area>415</area> <prefix>555</prefix> <number>1234</number> </phone> <phone type="home"> <area>415</area> <prefix>555</prefix> cnumber>5678</number> </phone> </address> <address id="77889"> <company>ThoughtWorks</company> <street>410 Townsend</street> <city>San Francisco</city> <state>CA</state> <postalcode>94107</postalcode> <country>USA</country> </address> </data> XML-документ содержит сведения о заказчике. Каждый заказчик может иметь не- сколько адресов, каждый из которых, в свою очередь, может содержать несколько теле- фонных номеров. Поскольку адреса представлены как независимые сущности, несколь- ко заказчиков могут иметь один адрес.
Транслятор сообщений (Message Translator) 121 Предположим, что система бухгалтерского учета ожидает получить XML-документ следующего вида (использование немецкого языка в именах тэгов не является чем-то сверхъестественным в области интеграции корпоративных приложений). <Kunde> <Name>Joe Doe</Name> <Adresse> <Strasse>123 Main</Strasse> <Ort>San Francisco</Ort> <Telefon>415-555-1234</Telefon> </Adresse> </Kunde> Приведенный выше XML-документ имеет более простую структуру, чем исходный. Кроме отличий в именах тэгов, некоторые поля исходного документа объединяются в единственное поле в целевом документе. Поскольку результирующая структура не позво- ляет заказчику иметь несколько адресов или телефонных номеров, необходимо выбрать соответствующие данные из исходного документа на основании существующих бизнес- правил. Следующая XSLT-программа выполняет преобразование формата исходного ХМ L-документа в требуемый формат. <xsl:stylesheet version="l.О" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:key name="addrlookup" match="/data/address" use="@id"/> <xsl:template match="data"> <xsl:apply-templates select="customer"/> </xsl:template> <xsl:template match="customer"> <Kunde> <Name> <xsl:value-of select="concat(firstname, 1 lastname)"/> </Name> <Adresse> <xsl:variable name="id" select="./address[@type='primary']/ref/@id"/> <xsl:call-template name="getaddr"> <xsl:with-param name="addr" select="key('addrlookup', $id)"/> </xsl: call-template;- </Adresse> </Kunde> </xsl:template> <xsl:template name="getaddr"> <xsl:param name="addr"/> <Strasse> <xsl:value-of select="$addr/street"/> </Strasse> <Ort> <xsl:value-of select="$addr/city"/> </Ort> <Telefon>
122 Глава 3. Системы обмена сообщениями <xsl:choose> <xsl:when test="$addr/phone[@type='cell' ] "> <xsl:apply-templates select="$addr/phone[@type=1 cell1]" mode="getphone"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="$addr/phone[@type='home']" mode="getphone" / > </xsl:otherwise> </xsl:choose> </Telefon> </xsl:template> <xsl:template match="phone" mode="getphone"> <xsl:value-of select="concat(area, prefix, number)"/> </xsl:template> <xsl:template match="*"/> </xsl:stylesheet> Приведенный выше код XSL основан на сопоставлении фрагментов текста. Коротко говоря, инструкции внутри элемента <xsl: template> выполняются всякий раз, когда в XML-документе встречается фрагмент, определенный атрибутом match. К примеру, строка <xsl:template match="customer"> указывает на необходимость выполнения последующих инструкций при обнаружении в исходном XML-документе тэга <customer>. В данном случае это приводит к формиро- ванию элемента <Name>, состоящего из имени и фамилии заказчика, а также элемента <Adresse>. Для извлечения из исходного XML-документа корректного адреса и теле- фонного номера код XSL вызывает процедуру getaddr. По умолчанию процедура getaddr извлекает номер мобильного телефона, а если он не определен— номер до- машнего телефона. Пример: визуальные средства преобразования Большинство разработчиков средств интеграции включают в состав своих продуктов ви- зуальный редактор преобразований, отображающий на экране структуру исходного и це- левого форматов документа. Пользователю предоставляется возможность ассоциировать требуемые элементы путем их соединения линиями. Подобный подход к выполнению преобразований гораздо проще, нежели код XSL. Некоторые вендоры, такие как Contivo, специализируются исключительно на создании средств преобразования. На рис. 3.8 показано окно редактора преобразования Microsoft BizTalk Mapper, интег- рированного в Visual Studio.
Транслятор сообщений (Message Translator) 123 Рис. 3.8. Создание преобразования с помощью перетаскивания Безусловно, преобразование элементов гораздо удобнее наблюдать на диаграмме, чем в коде XSL. С другой стороны, детали реализации (например, логика выбора телефон- ного номера) скрыты за так называемыми функциональными пиктограммами. Возможность создания преобразования путем перетаскивания существенно упрощает разработку транслятора сообщений (Message Translator). Тем не менее как только речь за- ходит об отладке кода или создании сложного интеграционного решения, визуальное представление преобразования становится скорее недостатком, чем достоинством. Именно поэтому многие визуальные средства преобразования позволяют переключаться между визуальным представлением и кодом XSL.
124 Глава 3. Системы обмена сообщениями Конечная точка сообщения (Message Endpoint) Приложения обмениваются сообщениями (Message, с. 98) по каналам сообщении (Message Channel, с. 93). Как подключить приложение к каналу системы обмена сообщениями? Приложение и система обмена сообщениями представляют собой две отдельные программные сущности. Приложение обеспечивает функциональность для пользовате- лей, в то время как система обмена сообщениями управляет каналами, применяющими- ся для передачи сообщений. Даже будучи встроенной в приложение, система обмена со- общениями предоставляет обособленные, специализированные функции подобно СУБД или Web-серверу. В связи с этим возникает задача подключения приложения к системе обмена сообщениями (рис. 3.9). Отправитель Сообщение Канал Получатель Рис. 3.9. Приложения не подключены к системе обмена сообщениями Система обмена сообщениями представляет собой определенный тип сервера, при- нимающего запросы и отвечающего на них. Подобно базе данных система обмена сооб- щениями принимает и доставляет сообщения. Таким образом, система обмена сообще- ниями является сервером сообщений. Клиентом сервера сообщений является приложение, взаимодействующее с другими приложениями с помощью обмена сообщениями. Подобно серверу баз данных сервер сообщений предоставляет клиентский API, с помощью которого приложение может взаимодействовать с сервером. Поскольку клиентский API сервера сообщений отражает специфику конкретной системы обмена сообщениями, приложение должно включать в себя код подключения к системе обмена сообщениями. Подключите приложение к каналу обмена сообщениями с помощью конечной точки сообщения (Message Endpoint)— клиента системы обмена сообщениями, позво- ляющего приложению отправлять и принимать сообщения (Message, с. 98). Отправитель Получатель
Конечная точка сообщения (Message Endpoint) 125 Код конечной точки сообщения (Message Endpoint) создается с учетом особенностей конкретного приложения и клиентского API системы обмена сообщениями. Оставшаяся часть приложения не обладает сведениями о формате сообщений, каналах и других под- робностях взаимодействия посредством обмена сообщениями. Конечная точка сообще- ния принимает от приложения команду или данные, формирует из них сообщение и от- правляет его в требуемый канал сообщений. Кроме того, конечная точка получает сооб- щение от системы обмена сообщениями и передает его содержимое приложению в понятном для него формате. Конечная точка сообщения инкапсулирует систему обмена сообщениями от приложе- ния. Таким образом, внесение изменений в приложение или в клиентский API системы обмена сообщениями приведет к необходимости правки кода только конечной точки сообщения. Конечная точка сообщения может использоваться для отправки или получения сооб- щений, однако она не может совмещать в себе обе функции. Кроме того, конечная точка сообщения создается для обслуживания конкретного канала сообщений. Таким образом, для взаимодействия по нескольким каналам сообщений приложение должно располагать соответствующим числом конечных точек сообщения. Приложение может использовать несколько конечных точек сообщения и при обслуживании одного канала, как правило, для под держки нескольких параллельных потоков сообщений. Конечная точка сообщения является частным случаем адаптера канала (Channel Adapter, с. 154), интегрированного в приложение и созданного для его подключения к конкретной системе обмена сообщениями. Конечная точка сообщения должна проектироваться как шлюз обмена сообщениями (Messaging Gateway, с. 482), что позволит скрыть систему обмена сообщениями от прило- жения. Она может включать в себя преобразователь обмена сообщениями (Messaging Mapper, с. 491) для передачи данных между объектами домена и сообщениями. Конечная точка сообщения может быть структурирована как активатор службы (Service Activator, с. 545), обеспечивая асинхронный доступ к синхронной службе или вызову функции. Наконец, она может выступать в роли транзакционного клиента (Transactional Client, с. 498) по отношению к системе обмена сообщениями. Различные типы конечных точек реализуют разные подходы к получению сообщений. Получатель сообшений может быть как опрашивающим потребителем (Polling Consumer, с. 507), так и событийно управляемым потребителем (Event-Driven Consumer, с. 511). Несколько потребителей могут извлекать сообщения из одного и того же канала с помо- щью диспетчера сообщений (Message Dispatcher, с. 521) или в соответствии с моделью кон- курирующих потребителей (Competing Consumers, с. 515). Для реализации логики фильтра сообщений получатель может применить шаблон избирательного потребителя (Selective Consumer, с. 528). С помощью шаблона постоянный подписчик (Durable Subscriber, с. 535) получатель гарантированно не пропустит ни одного сообщения, а с помощью шаблона идемпотентный получатель (Idempotent Receiver, с. 541) обеспечит защиту от дублирова- ния сообщений.
126 Глава 3. Системы обмена сообщениями Пример: классы Messageproducer и Messageconsumer (JMS) Два основных типа конечных точек сообщений в JMS представлены классами MessageProducer (используется для отправки сообщений) и Messageconsumer (используется для получения сообщений). Конечная точка сообщения (Message Endpoint) использует экземпляр одного из этих классов для отправки или получения сообщений по соответствующему каналу. Пример: класс MessageQueue (.NET) В .NET конечная точка сообщения (Message Endpoint) и канал сообщений (Message Channel, с. 93) представлены одним и тем же классом—MessageQueue. Конечная точка сообще- ния использует экземпляр класса MessageQueue для отправки или получения сообще- ний по соответствующему каналу.
Глава 4 Каналы обмена сообщениями Введение В предыдущей главе рассматривался канал сообщений (Message Channel, с. 93). Когда двум приложениям необходимо обменяться данными, они размещают их в канале, свя- зывающем эти приложения. Приложение, отправляющее данные, может и не знать, ка- кое приложение их получит. Но это и не требуется — выбор конкретного канала для от- правки данных гарантирует, что приложение, потребляющее данные указанного типа на другом конце канала, и есть требуемый получатель. Благодаря этому приложения, кото- рые поставляют общие данные, получают возможность взаимодействовать с приложе- ниями, которые хотят эти данные потреблять. Основные вопросы, связанные с применением каналов обмена сообщениями Вопрос использования канала сообщений (Message Channel, с. 93) решается сам собой; если приложение желает передать или получить данные, ему так или иначе придется ис- пользовать канал. Проблема состоит в другом: какие каналы нужны приложению и для чего оно их будет использовать? • Фиксированный набор каналов. Прежде всего отметим, что набор каналов сообще- ний, доступных приложению, носит постоянный характер. Разработчик приложе- ния должен знать, где следует размещать данные того или иного типа, чтобы поде- литься ими с другими приложениями, и наоборот, где искать данные конкретного типа, поступившие от других приложений. Указанные маршруты взаимодействия не могут создаваться динамически и обнаруживаться приложением во время вы- полнения; они должны быть согласованы еще во время разработки, чтобы прило- жение знало, откуда поступают данные и куда они уходят. Как всегда, из любого правила есть исключения: в некоторых ситуациях более практичными оказывают- ся именно динамические каналы. В качестве одного из таких исключений можно привести канал ответа в шаблоне запрос-ответ (Request-Reply, с. 177). Отправитель запроса может создать или получить в свое распоряжение новый канал, неизвест- ный ответчику, и задать его координаты в виде обратного адреса (Return Address, с. 182) сообщения с запросом. После этого получатель запроса сможет воспользо- ваться указанным каналом д ля отправки ответа на запрос. Еще одним исключени-
128 Глава 4. Каналы обмена сообщениями ем являются реализации систем обмена сообщениями, поддерживающих работу с иерархическими каналами. Если получатель подпишется на родительский канал, а отправитель опубликует свое сообщение в новом дочернем канале, неизвестном получателю, сообщение все равно дойдет до получателя. Впрочем, такие ситуации действительно встречаются редко. В большинстве случаев каналы задаются еще до развертывания приложений, а те, в свою очередь, разрабатываются с учетом зара- нее известного набора каналов. • Определение набора каналов. Предыдущий вопрос неразрывно связан с вопросом “Кто решает, какие каналы сообщений будут доступны приложению: система обме- на сообщениями или само приложение?”. Другими словами, должна ли система обмена сообщениями определить несколько каналов и в дальнейшем требовать, чтобы приложения использовали именно их? Или же приложения определяют, ка- кие каналы им нужны, после чего требуют, чтобы система обмена сообщениями предоставила им указанные каналы? Простого ответа на этот вопрос не существу- ет; определение необходимого набора каналов — итеративный процесс. Вначале приложения решают, какие каналы должны быть предоставлены системой обмена сообщениями. Остальные приложения пытаются организовать обмен данными с помощью набора существующих каналов, но, если взаимодействие оказывается неэффективным, они требуют добавления еще нескольких каналов. Если группа приложений уже использует устоявшийся набор каналов, то те приложения, кото- рые присоединяются к обмену данными, тоже будут работать с указанным набо- ром каналов. В свою очередь, при добавлении к существующим приложениям новой функциональности могут потребоваться новые каналы. • Однонаправленные каналы. Довольно много путаницы вызывает вопрос о типе кана- ла сообщений: он однонаправленный или двунаправленный? С технической точки зрения — ни тот, ни другой; канал сообщений больше похож на емкость, в которую одни приложения помещают данные, а другие их извлекают. (Емкость эта, правда, неким согласованным способом распределена между многими компьютерами.) Но поскольку данные находятся в сообщениях, которые “путешествуют” от одного при- ложения к другому, канал становится направленным, причем однонаправленным. Ес- ли бы канал был двунаправленным, это бы значило, что приложение отправляет и получает сообщения из одного и того же канала. С технической точки зрения такое решение возможно, но с практической вряд ли имеет смысл, ведь приложение будет потреблять собственные сообщения, которые предполагалось отправлять другим приложениям. По этой причине каналы сообщений делаются однонаправленными. Как следствие этого для пары приложений, обменивающихся данными в обоих на- правлениях, понадобится два канала сообщений: по одному на каждое направление. (См. также шаблон запрос-ответ в следующей главе.) Решения Итак, вы поняли, что такое каналы сообщений (Message Channel, с. 93). Теперь давайте рассмотрим, какой шаблон канала следует выбирать в той или иной ситуации • “Один-к-одному” или “один-ко-многим”. Если приложение размещает в канале свои данные, должны ли они быть доступны только одному получателю или же ими могут воспользоваться любые приложения, для которых эти данные представ-
Введение 129 ляют интерес? Чтобы отправить данные только одному приложению, воспользуй- тесь каналом “точка-точка” (Point-to-Point Channel, с. 131). Последний не гаранти- рует, что все данные, размещенные в канале, обязательно попадут к одному и тому же получателю, потому что у канала может быть много получателей. Тем не менее каждое отдельное сообщение будет получено одним и только одним приложением. Если же вы хотите, чтобы данными, размещенными в канале, смогли воспользо- ваться любые получатели, выберите канал “публикация-подписка” (Publish-Sub- scribe Channel, с. 134). В этом случае отправленное сообщение будет скопировано для каждого из получателей. Тип данных. Любые данные, хранящиеся в памяти компьютера, должны соответст- вовать какому-то типу: стандартному формату либо структуре с заранее согласо- ванным значением. В противном случае данные будут представлять собой не более чем набор нулей и единиц; превратить их в что-либо осмысленное не удастся. Подобным образом функционируют и системы обмена сообщениями. Содержи- мое сообщения должно соответствовать определенному типу, чтобы получатель смог понять структуру его данных. В основе канала типа данных (Datatype Channel, с. 139) лежит идея о том, что все сообщения в канале должны быть одного и того же типа. Вот основная причина того, почему системе обмена сообщениями требу- ется много каналов. Если бы данные могли иметь любой тип, для взаимодействия двух любых приложений системе обмена сообщениями понадобилось бы только по одному каналу (в каждом направлении). Неверные и недоставленные сообщения. Система обмена сообщениями обеспечи- вает корректную доставку последних, но не гарантирует, что получатель сможет обработать сообщение. Получатель ожидает, что принятые им данные будут иметь определенный тип и значение. Но что если полученное сообщение не соответству- ет его ожиданиям? Все, что можно сделать со странными сообщениями, — это поместить их в специальный канал недопустимых сообщений (Invalid Message Channel, с. 143) в надежде, что какая-нибудь служебная программа, которая осуще- ствляет мониторинг канала, “выловит” сообщение и поймет, что с ним делать. Во многих системах обмена сообщениями присутствует похожее встроенное сред- ство, а именно — канал недоставленных сообщений (Dead Letter Channel, с. 147). Туда помещаются сообщения, которые были успешно отправлены, но по какой- либо причине не могут быть успешно доставлены. Опять-таки, за каналом должна наблюдать некоторая служебная программа, которая будет решать, что делать с недоставленными сообщениями. Защита от сбоев. Если система обмена сообщениями даст сбой или будет закрыта на обслуживание, что произойдет с сообщениями? Останутся ли сообщения в канале, когда система вновь вернется к работе? По умолчанию нет; содержимое каналов хранится в оперативной памяти. Тем не менее шаблон гарантированная доставка (Guaranteed Delivery, с. 149) делает каналы постоянными, обеспечивая сохранность сообщений на диске. Это снижает производительность, зато повышает надежность обмена сообщениями, даже если сама инфраструктура то и дело отказывает. Клиенты, не предназначенные для обмена сообщениями. Что если приложение не может подключиться к системе обмена сообщениями, но все равно стремится уча- ствовать в этом процессе? В обычных условиях это бы не удалось, но если система
130 Глава 4. Каналы обмена сообщениями обмена сообщениями может хоть как-то подключиться к приложению — через его пользовательский интерфейс, интерфейсы API его бизнес-служб, его базу данных либо сетевое соединение наподобие TCP/IP или HTTP, — тогда для связи прило- жения с системой обмена сообщениями можно воспользоваться адаптером канала (Channel Adapter, с. 154). Благодаря этому приложение можно будет подсоединить к каналу или набору каналов без необходимости вносить изменения в приложение (а также, вероятно, без необходимости размещать клиент обмена сообщениями на том же компьютере, что и само приложение). Иногда клиент, якобы “не предна- значенный для обмена сообщениями”, в действительности оказывается клиентом обмена сообщениями, только другой системы. В этом случае приложение, являю- щееся клиентом обеих систем обмена сообщениями, может объединить их в одну, связав их при помощи моста обмена сообщениями (Messaging Bridge, с. 159). » Vfc MSpt 'ТОГО Ш нии подключаются к системе обмена сообщениями и делают свою функциональ- ность доступной для других приложений через отправку и получение сообщений, система обмена сообщениями становится центральной точкой выбора и использо- вания общей функциональности корпоративной системы. Новому приложению требуется лишь знать, какие каналы нужно использовать для запроса функцио- нальности, а какие прослушивать в ожидании ответа. Система обмена сообще- ниями, по сути, превращается в шину сообщений (Message Bus, с. 162), магистраль, предоставляющую доступ к абсолютно всем (пусть даже неоднородным и посто- янно меняющимся) приложениям и функциональности корпоративной системы. Ориентируясь на такое предназначение системы обмена сообщениями с самого начала ее разработки, можно быстрее и легче достичь интеграционной “нирваны”. Как видите, настройка корпоративных приложений для обмена сообщениями (Messaging, с. 87) требует большего, чем просто их подключения к системе обмена сооб- щениями. Сообщения должны передаваться по каналам сообщений, но “нашлепать” несколько каналов на скорую руку тоже недостаточно. Каналы должны разрабатываться специально для передачи данных определенного типа, с учетом типов приложений, отправляющих и получающих данные. В настоящей главе мы рассмотрим шаблоны про- ектирования, применяющиеся для решения этой проблемы. Чтобы лучше проиллюстрировать действие шаблонов, описание каждого из них снабжено примером создания вымышленной системы биржевой торговли через Интер- нет. Хотя ни один из этих примеров не должен применяться как основа для разработки реальной системы торговли на бирже, они хорошо служат в качестве наглядного пособия по использованию шаблонов.
Канал “точка-точка” (Point-to-Point Channel) 131 Канал “точка-точка” (Point-to-Point Channel) Приложение использует обмен сообщениями (Messaging, с. 87) для удаленного вызова процедур или передачи документов. Может ли приложение, отправившее документ или вызвавшее процедуру, гаранти- ровать, что документ или вызов будет получен только одним приложением? Одно из преимуществ удаленного вызова процедуры (Remote Procedure Call — RPC) заключается в том, что он выполняется в рамках одного удаленного процесса, т.е. получа- тель вызова либо выполнит процедуру, либо не выполнит ее (и будет сгенерировано исклю- чение). А поскольку получатель вызывается только один раз, процедура тоже будет выпол- нена единожды. Но если вызов процедуры будет упакован в сообщение (Message, с. 98) и размещен в канале сообщений (Message Channel, с. 93), несколько получателей могут уви- деть сообщение и решить, что вызов процедуры предназначается именно для них. Система обмена сообщениями могла бы следить за тем, чтобы канал прослушивался только одним получателем, но это несправедливо ограничит возможности приложений, которые хотели бы отправить данные нескольким получателям. Получатели, наблюдаю- щие за каналом, могли бы согласовывать свои действия, чтобы вызываемая процедура выполнялась только одним из них. Это, однако, привело бы к перегрузке коммуникаци- онных линий и усилило связь между получателями, которые обычно не зависят друг от друга. Итак, канал должны прослушивать много получателей (чтобы параллельно обра- батывать поступающие сообщения), но каждое отдельное сообщение должен потреблять один и только один получатель. Чтобы сообщение было принято только одним получателем, отправьте его по каналу “точка-точка" (Point-to-Point Channel). Отправитель Заказ Заказ Заказ №3 №2 №1 Канал “точка-точка" Заказ Заказ Заказ №3 №2 №1 Получатель Канал “точка-точка” гарантирует, что каждое отдельное сообщение будет потреблено только одним получателем. У канала может быть много получателей, одновременно об- рабатывающих сообщения, но только один из них сможет успешно принять конкретное сообщение. Если несколько получателей попытаются одновременно потребить некото- рое сообщение, канал сам позаботится о том, чтобы эта операция удалась только одному из них. Координировать свои действия получателям не придется. Если у канала “точка-точка” только один получатель, факт, что сообщение будет по- треблено только один раз, едва ли можно назвать удивительным. Если же канал прослу-
132 Глава 4. Каналы обмена сообщениями шивается несколькими получателями, они становятся конкурирующими потребителями (Competing Consumers, с. 515), и канал гарантирует, что сообщение будет получено только од- ним из них. Такая схема потребления и обработки сообщений прекрасно масштабируется, поскольку рабочая нагрузка на канал может быть распределена между несколькими потре- бителями, запущенными в рамках нескольких приложений на нескольких компьютерах. Если сообщение должно быть получено не одним, а всеми получателями, которые прослушивают канал, используйте канал “публикация-подписка” (Publish-Subscribe Channel, с. 134). И наконец, чтобы реализовать удаленный вызов процедуры через обмен сообщениями, воспользуйтесь шаблоном запрос-ответ (Request-Reply, с. 177) в сочетании с парой каналов “точка-точка”. Вызов процедуры будет представлять собой сообщение с командой (Command Message, с. 169), а ответ на вызов — сообщение с данными документа (Document Message, с. 171). Пример: торговля на бирже В системе биржевой торговли запрос на осуществление торговой операции (покупки или продажи) передается в виде сообщения, которое должно быть принято и выполнено в точности одним получателем, поэтому сообщение следует отправить по каналу “точка- точка” (Point-to-Point Channel). Пример: объект Queue (JMS) В JMS канал “точка-точка” (Point-to-Point Channel) реализован через интерфейс Queue. Отправитель использует объект Queuesender, а каждый из получателей — собственный объект QueueReceiver [14, 17]. Вот как в приложении может использоваться объект Queuesender для отправки со- общения. Queue queue = // Получить очередь сообщений через JNDI. QueueConnectionFactory factory = // Получить фабрику соединений // через JNDI. Queueconnection connection = factory.createQueueConnectionО; QueueSession session = connection.createQueueSession(true. Session.AUTO_ACKNOWLEDGE); Queuesender sender = session.createSender(queue); Message message = session.createTextMessage("The contents of the message."); sender.send(message); А вот как приложение использует объект QueueReceiver, чтобы получить сообщение. Queue queue = // Получить очередь сообщений через JNDI. QueueConnectionFactory factory = // Получить очередь сообщений // через JNDI. QueueConnection connection = factory.createQueueConnection(); QueueSession session = connection.createQueueSession(true. Session.AUTO_ACKNOWLEDGE) ,-
Канал “точка-точка" (Point-to-Point Channel) 133 QueueReceiver receiver = session.createReceiver(queue) ; TextMessage message = (TextMessage) receiver.receive(); String contents = message.getText(); Примечание. В спецификации JMS l.l клиентские интерфейсы API для каналов “точка-точка” и “публикация-подписка” унифицированы, поэтому код, показанный здесь, можно упростить, используя объекты Destination, ConnectionFactory, Connection, Session, Messageproducer и Messageconsumer вместо соответствующих Queue-аналогов. Пример: объект MessageQueue (.NET) В .NET канал “точка-точка” (Point-to-Point Channel) реализован при помощи класса MessageQueue [39]. Кстати, служба MSMQ, которая реализует обмен сообщениями на платформе .NET, до выхода версии 3.0 поддерживала только обмен сообщениями по принципу “точка-точка”. В отличие от JMS, разделяющей функции фабрики соединений, соединения, сеанса, отправителя и очереди сообщений, в .NET за выполнение обязанностей всех указанных объектов отвечает MessageQueue. Отправка сообщения происходит следующим образом. MessageQueue queue = new MessageQueue("MyQueue") ; queue.Send("The contents o£ the message."); Получение сообщения при помощи объекта MessageQueue выглядит так. MessageQueue queue = new MessageQueue("MyQueue"); Message message = queue.Receive(); String contents = (String) message.Body();
134 Глава 4. Каналы обмена сообщениями Канал “публикация-подписка” (Publish-Subscribe Channel) ------► --------> Приложение использует обмен сообщениями (Messaging, с. 87) для оповещения о собы- тиях. Как оповестить о событии всех заинтересованных получателей? Для реализации широковещательной рассылки существуют хорошо известные, прове- ренные решения. Шаблон проектирования наблюдатель (Observer) из [12] описывает необ- ходимость разобщения наблюдателей и субъекта (т.е. инициатора события), чтобы субъект мог легко организовать оповещение о событии всех заинтересованных наблюдателей вне зависимости от их количества (даже если оно равно нулю). Расширением наблюдателя яв- ляется шаблон издатель-подписчик (Publisher-Subscriber) из [33]. В него добавлено описание канала событии, специально предназначенного для оповещения о событиях. Это все теория, но как она применяется к системе обмена сообщениями? Сведения о событии могут быть упакованы в сообщение (Message, с. 98), чтобы обеспечить надежное оповещение наблюдателей (подписчиков). Тогда в качестве канала событий должен при- меняться канал сообщений (Message Channel, с. 93). Но как сделать так, чтобы канал обме- на сообщениями корректно оповестил о событии всех подписчиков? Каждый подписчик должен быть оповещен о конкретном событии, но только один раз. Сообщение о событии не может считаться потребленным, пока уведомление не по- лучат все подписчики; когда же это произойдет, сообщение считается потребленным и должно быть удалено из канала. Однако необходимость подписчиков координировать свои действия при потреблении сообщений нарушает принцип разобщения, провозгла- шенный в шаблоне наблюдатель. Потребители не должны конкурировать друг с другом, но при этом должны иметь возможность совместно использовать сообщение о событии. Чтобы копию сообщения о событии получил каждый подписчик канала, отправьте сообщение по каналу “публикация-подписка”(Publish-Subscribe Channel). Канал “публикация-подписка” функционирует следующим образом: у него есть один входной канал, который разбивается на несколько выходных каналов, по одному на каж- дого подписчика. Когда оповещение о событии публикуется в канале, канал “публикация- подписка” доставляет копию сообщения в каждый из выходных каналов. На каждом “выходе” канала есть только один подписчик, которому разрешается потреблять сооб- щение только один раз. Благодаря этому каждый подписчик получит сообщение только единожды, после чего потребленные копии сообщения исчезнут из соответствующих вы- ходных каналов.
Канал “публикация-подписка” (Publish-Subscribe Channel) 135 Канал “публикация-подписка” Адрес изменился Подписчик Адрес изменился Подписчик Адрес изменился Подписчик Помимо всего прочего, канал “публикация-подписка” удобно применять для отладки. Даже если сообщение предназначено для одного получателя, использование канала “публикация-подписка” позволяет прослушивать канал сообщений, не вмешиваясь в су- ществующий поток сообщений. Мониторинг трафика, передающегося по каналу, может оказаться необычайно полезным при отладке приложений, использующих обмен сооб- щениями. Он также избавит разработчика от необходимости вставлять в код приложе- ний, участвующих в обмене сообщениями, сотни выражений с оператором Print. Соз- дание программы, которая бы прослушивала все активные каналы на предмет сообще- ний и записывала сведения о них в журнал, может принести не меньше пользы, нежели хранилище сообщений (Message Store, с. 565). Возможность свободного прослушивания канала “публикация-подписка” имеет и нега- тивные стороны. Если система обмена сообщениями передает данные о зарплате между системой начисления заработной платы и системой бухгалтерского учета, вряд ли вам за- хочется, чтобы кто-то мог написать простую программу, посредством которой он будет прослушивать трафик сообщений. При использовании канала “точка-точка” указанная проблема несколько смягчается: поскольку программа, прослушивающая сообщения, будет считаться их потребителем (а сообщение, потребленное один раз, удаляется из ка- нала), сообщения внезапно начнут исчезать, не доходя до истинных получателей, что не- замедлительно будет обнаружено. Тем не менее во многих реализациях очереди сообще- ний присутствуют функции, которые позволяют потребителям взглянуть на сообщения, стоящие в очереди, не потребляя их. Как следствие этого подписка на канал сообщений должна ограничиваться политиками безопасности. Последние внедрены во многие (но не во все) коммерческие реализации систем обмена сообщениями. Вдобавок ко всему средство мониторинга, которое будет фиксировать в журнале активных подписчиков ка- налов сообщений, может пригодиться для управления системой.
136 Глава 4. Каналы обмена сообщениями Подписка на каналы при помощи символов подстановки Многие системы обмена сообщениями позволяют подписчикам каналов “публикация- подписка” (Publish-Subscribe Channel) использовать специальные символы подстановки. Это очень мощный прием, благодаря которому потребители сообщений могут подпи- саться сразу на несколько каналов. К примеру, если некоторое приложение публикует свои сообщения в каналах MyCorp/Prod/OrderProcessing/NewOrders и МуСогр/ Prod/OrderProcessing/CancelledOrders, другое приложение может подписаться на канал MyCorp/Prod/OrderProcessing/* и получать все сообщения, касающиеся об- работки заказов. Еще одно приложение может подписаться на МуСогр/Dev/*, чтобы по- лучать все сообщения, отправленные приложениями в среде разработки. Использовать символы подстановки разрешается только подписчикам; издатели всегда должны публи- ковать сообщения в точно заданном канале. Точный синтаксис и возможности символов подстановки зависят от производителя системы обмена сообщениями. Сообщение о событии (Event Message, с. 174) часто отправляется по каналу “публикация- подписка”, поскольку в оповещении о событии обычно заинтересовано множество сис- тем. Подписчики могут быть постоянными или временными (см. шаблон постоянный подписчик (Durable Subscriber, с. 535)). Если оповещения должны быть подтверждены подписчиками, используйте шаблон запрос-ответ (Request-Reply, с. 177), в котором опо- вещение будет запросом, а подтверждение — ответом. Хранение каждого сообщения в канале “публикация-подписка” до тех пор, пока оно не будет получено всеми подписчика- ми, может потребовать большого количества ресурсов. Для устранения этой проблемы сообщениям, отправляемым по каналу “публикация-подписка”, можно назначить срок действия сообщения (Message Expiration, с. 198). Пример: торговля на бирже В системе биржевой торговли о совершении торговой операции (например, покупки или продажи акций) должны быть оповещены сразу несколько систем. Сделайте их подпис- чиками канала “публикация-подписка” (Publish-Subscribe Channel), в котором будут разме- щаться сообщения о выполненных операциях. Аналогичным образом многие потребители будут заинтересованы в отображении или обработке текущих биржевых котировок. Таким образом, котировки должны распро- страняться через канал “публикация-подписка”. Пример: объект Topic (JMS) В JMS канал “публикация-подписка” (Publish-Subscribe Channel) реализован через интер- фейс Topic. Отправитель использует объект Topicpublisher, а каждый из получате- лей — собственный объект Topicsubscriber [14, 17]. Вот как в приложении используется объект TopicPublisher для отправки широко- вещательного сообщения. Topic topic = // Получить тему через JNDI. TopicConnectionFactory factory = // Получить фабрику соединений // через JNDI.
Канал “публикация-подписка” (Publish-Subscribe Channel) 137 TopicConnection connection = factory.createTopicConnection(); TopicSession session = connection.createTopicSession(true. Session.AUTO_ACKNOWLEDGE); TopicPublisher publisher = session.createPublisher(topic); Message message = session.createTextMessage("The contents of the message."); publisher.publish(message); А вот как приложение использует объект Topicsubscriber, чтобы получить широ- ковещательное сообщение. Topic topic = // Получить тему через JNDI. TopicConnectionFactory factory = // Получить фабрику соединений // через JNDI. TopicConnection connection = factory.createTopicConnectionО; TopicSession session = connection.createTopicSession(true. Session.AUTO_ACKNOWLEDGE); Topicsubscriber subscriber = session.createSubscriber(topic); TextMessage message = (TextMessage) subscriber.receive(); String contents = message.getText(); Примечание. В спецификации JMS 1.1 клиентские интерфейсы API для каналов “точка-точка” и “публикация-подписка” унифицированы, поэтому код, показанный здесь, можно упростить, используя объекты Destination, ConnectionFactory, Connection, Session, Messageproducer и Messageconsumer вместо соответствующих Topic-аналогов. Пример: обмен сообщениями по принципу “один-ко-многим” (MSMQ) В версии MSMQ 3.0 [29] появилась модель обмена сообщениями “один-ко-многим”. Существует два разных подхода к ее реализации. 1. Многоадресная рассылка сообщений в режиме реального времени. Этот подход ближе к концепции канала “публикация-подписка” (Publish-Subscribe Channel), но его реализация полностью зависит от многоадресной рассылки IP через протокол PGM (Pragmatic General Multicast). По этой причине указанный подход не может быть использован с протоколами, не основанными на IP. 2. Списки рассылки и многоэлементные имена форматов. Список рассылки (Distribution List) позволяет отправителю явно разослать сообщение списку полу- чателей. Это, однако, нарушает концепцию шаблона наблюдатель (Observer), потому что отправитель теперь должен знать о получателях. Таким образом, дан- ное средство скорее напоминает список получателей (Recipient List, с. 264), нежели канал “публикация-подписка”. Многоэлементное имя формата (Multiple-Element Format Name) задает символический канал, который динамически отображается на несколько реальных каналов. Это уже ближе к концепции канала “публикация- подписка”, но все равно требует, чтобы отправитель выбирал между реальным и символическим каналами.
138 Глава 4. Каналы обмена сообщениями Общая языковая среда выполнения (Common Language Runtime — CLR), в которой выполняются приложения .NET, не обеспечивает прямую поддержку модели обмена со- общениями “один-ко-многим”. Тем не менее доступ к этой функциональности можно осуществить через интерфейс СОМ [24], который может быть внедрен в код .NET. Пример: простой обмен сообщениями В главе 6 приведен пример реализации механизма публикации-подписки с помощью JMS. Он показывает, как реализовать шаблон наблюдатель {Observer) в распределенной среде, используя обмен сообщениями.
Канал типа данных (Datatype Channel) 139 Канал типа данных (Datatype Channel) Приложение использует обмен сообщениями (Messaging, с. 87) для передачи данных различных типов, например разнообразных документов. Как приложение должно отправить данные, чтобы получатель знал, как их обраба- тывать? Что такое сообщения? Это всего лишь экземпляры одного и того же класса сообще- ний, определенного системой обмена сообщениями. Содержимое сообщения представ- ляет собой обычный массив байтов. Хотя такой простой структуры достаточно для пере- дачи сообщения, ее недостаточно, чтобы получатель смог обработать сообщение долж- ным образом. Получатель должен знать структуру данных, отправленных в теле сообщения, и фор- мат этих данных. Структура данных может представлять собой массив символов, массив байтов, сериализованный объект, документ XML и т.п. Формат — это, в свою очередь, записи с полями данных для байтов или символов, класс для сериализованного объекта, определение схемы для документа XML и т.п. Совокупность этих деталей (т.е. структуры и формата) иногда называют типом сообщения. Получателя нужно уведомить о том, к какому типу принадлежит принятое им сооб- щение. В противном случае он не будет знать, как его обрабатывать. Пусть, к примеру, отправитель хочет отослать несколько объектов, таких как заказы на поставку, прайс- листы и запросы. Разумеется, для обработки каждого из них получателю придется вы- полнить различные действия, поэтому он должен знать, к какому типу принадлежит то или иное сообщение. Если все сообщения будут просто отправлены по единому каналу обмена сообщениями, получатель не поймет, как обрабатывать каждое из них (рис. 4.1). Отправитель Запрос Прайс-лист Заказ на поставку Рис. 4.1. Данные разных типов Канал Получатель Отправитель прекрасно знает, сообщение какого типа он отсылает, но как уведомить об этом получателя? Отправитель мог бы поместить в заголовок сообщения некий флаг, как описывается в шаблоне индикатор формата (Format Indicator, с. 201), но тогда полу- чателю потребуется оператор выбора наподобие Case Of. Данные можно было бы упа- ковать в сообщение с командой (Command Message, с. 169) с отдельной командой для каж- дого типа данных. Но отправляя сообщение с командой, мы будто бы уведомляем получа- теля о том, что с данными нужно что-то сделать (а ведь сообщение отправляется лишь затем, чтобы просто донести данные до получателя!).
140 Глава 4. Каналы обмена сообщениями Аналогичная проблема (на сей раз не связанная с сообщениями) возникает при обра- ботке коллекции элементов. Коллекция должна быть гомогенной, т.е. все ее элементы должны иметь один и тот же тип, чтобы обработчик заранее знал, как ими манипулиро- вать. Между тем во многих реализациях коллекции ее элементам вовсе не обязательно иметь определенный тип. По этой причине программисты вынуждены вставлять в код проверку, принадлежат ли все элементы коллекции к одному и тому же типу. В против- ном случае в коллекции могут оказаться элементы разных типов, и обработчик не пой- мет, как именно следует обрабатывать тот или иной элемент. Описанный принцип справедлив и для обмена сообщениями, поскольку все сообще- ния в канале должны принадлежать к одному и тому же типу. Самое простое решение в этой ситуации — сделать так, чтобы все сообщения имели один и тот же формат; если же форматы должны отличаться, снабдить каждое сообщение надежным индикатором формата. Хотя специфика канала не обязывает сообщения иметь один и тот же тип, этого требует получатель, которому нужно знать, как обрабатывать сообщения. Используйте для каждого типа данных отдельный канал типа данных (Datatype Channel), чтобы все данные в конкретном канале принадлежали к одному и тому Благодаря использованию отдельного канала типа данных для каждого типа данных все сообщения в конкретном канале будут содержать данные одного и того же типа. Отправитель, знающий, к какому типу принадлежат данные, выберет канал, в котором следует разместить сообщение. Получатель посмотрит, по какому каналу были доставле- ны данные, и поймет, какого они типа. Как показано на иллюстрации к шаблону, поскольку отправитель хочет отослать дан- ные трех разных типов (заказы на доставку, прайс-листы и запросы), он должен восполь-
Канал типа данных (Datatype Channel) 141 зоваться тремя каналами. Отсылая элемент данных, отправитель должен выбрать для него нужный канал типа данных. Принимая элемент данных, получатель автоматически определит его тип, потому что будет знать, по какому каналу типа данных он пришел. Канал качества обслуживания К концепции канала типа данных (Datatype Channel) близка такая стратегия, как канал качества обслуживания (quality-of-service channel). Пусть компании требуется передать некоторую группу сообщений с уровнем обслуживания, отличного от того, который применяется при передаче других сообщений. К примеру, входящие сообщения о но- вых заказах могут представлять собой основной источник дохода для бизнеса компа- нии, а посему должны передаваться по чрезвычайно надежному каналу — например, с использованием гарантированной доставки (Guaranteed Delivery, с. 149), — даже невзирая на потенциальное снижение производительности. С другой стороны, потеря сообщения, запрашивающего состояние заказа, — не такое уж неприятное событие, поэтому его можно отправить по быстрому, но менее надежному каналу. Требуемое качество обслуживания иногда можно обеспечить и при использовании единственного канала (например, с помощью приоритета сообщений). Тем не менее параметры каче- ства обслуживания обычно рекомендуется задавать при создании канала, а не пере- кладывать это решение на код приложения, которое будет отправлять сообщения. Таким образом, каждую группу сообщений лучше пересылать по собственному каналу со специально настроенным под их потребности качеством обслуживания. Как уже говорилось в разделе, посвященном каналу сообщений (Message Channel, с. 93), создание и поддержка каналов обходится недорого, но и не бесплатно. Поскольку при- ложению часто требуется передавать данные множества разных типов, создавать отдель- ный канал типа данных для каждого из них слишком накладно. В этом случае данные разных типов могут передаваться по одному каналу с использованием для каждого типа данных своего избирательного потребителя (Selective Consumer, с. 528). Благодаря этому один физический канал будет выступать в роли нескольких логических каналов типа дан- ных. Такая стратегия передачи данных называется мультиплексированием (multiplexing), или уплотнением. В то время как концепция канала типа данных разъясняет, почему все сообщения в канале должны иметь один и тот же формат, в шаблоне каноническая модель данных (Canonical Data Model, с. 367) показано, как сделать, чтобы все сообщения во всех каналах компании соответствовали некоторому общему формату данных. Если вы хотите использовать каналы типа данных, но существующий издатель сообще- ний упорно размещает сообщения в одном канале, можете воспользоваться маршрутизато- ром на основе содержимого (Content-Based Router, с. 247), чтобы демультиплексировать (разуплотнить) сообщения. Маршрутизатор распределяет поток сообщений по каналам типа данных, в каждом из которых содержатся сообщения только одного типа. Диспетчер сообщений (Message Dispatcher, с. 521), обеспечивающий параллельное по- требление сообщений, может также применяться для обработки смешанного набора со- общений согласно типу каждого из них. В каждом сообщении должен быть указан его тип (обычно это делается с помощью индикатора формата, вставленного в заголовок со- общения). Диспетчер определяет тип сообщения и передает его исполнителю, предна- значенному для обработки данных этого типа. Сообщения в канале все равно должны
142 Глава 4. Каналы обмена сообщениями принадлежать к одному и тому же типу, но это может быть более общий тип, поддержи- ваемый диспетчером, а не конкретный тип, подлежащий специфической обработке. Для того чтобы можно было различать версии одного и того же формата данных, при- меняется индикатор формата, который, в свою очередь, позволяет отсылать такие дан- ные по одному и тому же каналу типа данных. Пример: торговля на бирже Если в системе биржевой торговли формат запроса о котировках отличается от формата запроса на выполнение торговой операции, для отправки каждого из них следует приме- нять отдельный канал типа данных (Datatype Channel). Точно так оповещение об измене- нии адреса может по своему формату отличаться от оповещения о смене брокера, поэто- му каждый тип оповещения следует рассылать по собственному каналу типа данных.
Канал недопустимых сообщений (Invalid Message Channel) 143 Канал недопустимых сообщений (Invalid Message Channel) Приложение использует обмен сообщениями (Messaging, с. 87) для получения сообщений (Message, с. 98). Как поступить с сообщением, не несущим в себе никакого смысла для получателя? В теории все, что передается по каналу сообщений (Message Channel, с. 93), является обычным сообщением, а получатели просто обрабатывают принятые ими сообщения. Между тем, чтобы обработать сообщение, получатель должен уметь интерпретировать его данные и понимать их значение. Это не всегда возможно: в теле сообщения могут содер- жаться синтаксические, лексические или другие ошибки. В заголовке сообщения могут отсутствовать необходимые поля, или же эти поля могут иметь бессмысленные значения. Отправитель может создать вполне корректное сообщение, но разместить его в непра- вильном канале, что приведет к передаче сообщения не тому получателю. И наконец, злоумышленник может специально отправить некорректное сообщение, чтобы запутать получателя. Во всех перечисленных случаях получателю нужно придумать способ обра- ботки сообщений, которые кажутся ему ошибочными. Канал сообщений должен быть каналом типа данных (Datatype Channel, с. 139). Предпо- лагается, что каждое из находящихся в нем сообщений принадлежит к заданному для этого канала типу данных. Если отправитель разместит в канале сообщение не того типа, доставка сообщения пройдет успешно, но получатель не сможет определить тип сообще- ния и не будет знать, как его обработать. В качестве примера сообщения с неправильным типом данных можно привести число- вое сообщение, передающееся по каналу для текстовых сообщений. Еще один пример не- корректного формата сообщения — это неправильно оформленный документ XML либо документ, который не соответствует заранее согласованной схеме или шаблону DTD. С точки зрения системы обмена сообщениями в них нет ничего из ряда вон выходящего, но получатель не сможет их обработать, поэтому сообщения будут признаны недопустимыми. Сообщения, в заголовках которых нет полей, требующихся получателю, также счита- ются недопустимыми. Если в заголовке сообщения должны присутствовать такие поля, как идентификатор корреляции (Correlation Identifier, с. 186), идентификатор цепочки сооб- щений (Message Sequence, с. 192), обратный адрес (Return Address, с. 182) или другие подоб- ные свойства, но их нет, сообщение будет корректно доставлено, но обработать его полу- чателю не удастся (рис. 4.2). Отправитель Недопустимое Канал Получатель сообщение Рис. 4.2. Недопустимое сообщение
144 Глава 4. Каналы обмена сообщениями Что должен сделать получатель, если обнаружит, что сообщение, которое он пытается обработать, не является допустимым? Сообщение можно вернуть в канал, но тогда оно снова будет потреблено тем же получателем или кем-то подобным. Более того, сообще- ния неверного формата, которые игнорируются получателями, будут “захламлять” канал и негативно сказываться на производительности. Получатель может выбросить недопус- тимое сообщение, но это усложнит выявление проблем в схеме обмена сообщениями. Таким образом, системе нужен способ убрать неверные сообщения из канала и помес- тить их в такое место, где они не будут мешать потоку других сообщений, но могут быть найдены для диагностики проблем в системе обмена сообщениями. Получатель должен переместить сообщение неверного формата в канал недопус- тимых сообщений (Invalid Message Channel). Это специальный канал, предназна- ченный для сообщений, которые не могут быть обработаны своими получателями. Отправитель Сообщения Канал Получатель Недопустимое Канал сообщение недопустимых сообщений Разрабатывая систему для обмена сообщениями между приложениями, администратор должен определить один или несколько каналов недопустимых сообщений, которыми будут пользоваться эти приложения. Канал недопустимых сообщений не будет применяться для обычного взаимодействия приложений, а следовательно, его можно смело заполнять неверными сообщениями. Получателем, прослушивающим канал недопустимых сообщений, может стать обработчик ошибок, который будет диагностировать неверные сообщения. Канал недопустимых сообщений — это своеобразный журнал записи ошибок для систе- мы обмена сообщениями. Если в приложении что-то идет не так, ошибку рекомендуется зафиксировать в журнале. Если же проблемы возникают при обработке сообщения, его удобно поместить в канал для недопустимых сообщений. Кроме того, если причина некор- ректности сообщения не слишком очевидна (и программа, прослушивающая канал недо- пустимых сообщений, может не понять, почему туда попало указанное сообщение), прило- жение также должно зафиксировать в журнале ошибку с подробным описанием последней. Помните, что сообщение само по себе не является допустимым или недопустимым. Допустимость сообщения определяется лишь в контексте конкретного получателя и за- висит от того, какой формат данных тот ожидает. Сообщение, допустимое для одного по- лучателя, может оказаться недопустимым для другого. Такие получатели не должны делить между собой общий канал. Сообщение, допустимое для одного из получателей канала, должно быть допустимым и для всех остальных получателей этого же канала. Точно так же, если один из получателей канала сочтет некоторое сообщение недопусти- мым, оно должно считаться таковым и всеми остальными получателями этого канала. Отправитель сообщения должен позаботиться о том, чтобы оно оказалось допустимым для получателей, прослушивающих канал. В противном случае получатели будут игнориро- вать сообщения указанного отправителя, пересылая их в канал недопустимых сообщений.
Канал недопустимых сообщений (Invalid Message Channel) 145 Похожая (но другая) проблема возникает, если сообшение корректно структурировано, но имеет семантически неправильное содержимое. К примеру, в сообщении с командой (Command Message, с. 98) могут содержаться инструкции о необходимости удалить из базы данных определенную запись, но такой записи там не окажется. Это ошибка не системы обмена сообщениями, а приложения. С самим сообщением все в порядке, поэтому отправ- лять его в канал недопустимых сообщений не следует. Ошибка такого рода должна быть об- работана как недопустимый запрос приложения, а не как недопустимое сообщение. Разница между ошибками обработки сообщений и ошибками приложения становится проще и понятнее, если реализовать получателя как активатора службы (Service Activator, с. 545) или как шлюз обмена сообщениями (Messaging Gateway, с. 482). В указанных шабло- нах код обработки сообщений отделяется от остальных компонентов приложения. Если ошибка произойдет во время обработки сообщения, сообщение будет сочтено недопус- тимым и отправится в канал недопустимых сообщений. Если же она произойдет в процессе обработки приложением данных, извлеченных из сообщения, это ошибка приложения, не имеющая никакого отношения к обмену сообщениями. Канал недопустимых сообщений, содержимое которого игнорируется, несет в себе не больше пользы, нежели журнал записи ошибок, в который никто никогда не загляды- вает. Сообщения, помещенные в такой канал, свидетельствуют о проблемах, возникших в процессе интеграции приложений, а посему должны быть немедленно проанализиро- ваны. В идеале процесс потребления недопустимых сообщений, выяснения причины их появления и устранения соответствующих проблем должен быть автоматизирован. Но на практике причиной появления недопустимых сообщений часто является ошибка коди- рования или настройки, исправление которой невозможно без участия разработчика или системного аналитика. Но даже если автоматизация указанного процесса невозможна, у приложения, использующего систему обмена сообщениями и каналы недопустимых со- общений, по крайней мере, должен быть процесс, который следит за каналом недопусти- мых сообщений и оповещает системных администраторов о появлении в канале сообще- ний неверного формата. Во многих системах обмена сообщениями реализована похожая концепция под на- званием канал недоставленных сообщений (Dead Letter Channel, с. 147). В отличие от канала недопустимых сообщений, содержащего сообщения, которые были успешно доставлены и получены, но не обработаны, канал недоставленных сообщений предназначен для сообще- ний, которые не смогли быть доставлены системой обмена сообщениями. Пример: торговля на бирже Рассмотрим приложение, выполняющее запросы других приложений на осуществление торговых операций. Пусть оно по ошибке получает запрос о биржевых котировках либо запрос на осуществление покупки, в котором не будет указано, какой вид ценных бумаг следует приобрести, в каком количестве или же кому отправить подтверждение о совер- шении покупки. В каждом из этих случаев сообщение с запросом, полученное приложе- нием, будет рассматриваться как недопустимое, т.е. такое, которое не соответствует ми- нимальному набору требований, необходимых для обработки запроса на выполнение операции. Как только сообщение будет сочтено недопустимым, приложение-получатель должно направить его в канал недопустимых сообщений (Invalid Message Channel). Прило- жения, отсылающие запросы, по желанию могут наблюдать за каналом недопустимых сообщений, чтобы следить за тем, не был ли отброшен тот или иной запрос.
146 Глава 4. Каналы обмена сообщениями Пример: спецификация JMS В спецификации JMS говорится: если объект MessageListener получит сообщение, но не сможет его обработать, он должен перенаправить сообщение в “некоторый пункт назначения, специфичный для данного приложения и предназначенный для размещения сообщений, не поддающихся обработке” [17]. Этим “пунктом назначения” (destination) и является канал недопустимых сообщений (Invalid Message Channel). Пример: простой обмен сообщениями В главе 6 показано, как реализовать получателей, перенаправляющих сообщения, кото- рые не удалось обработать, в канал недопустимых сообщений (см. примеры реализации механизма “запрос-ответ” в JMS и .NET).
Канал недоставленных сообщений (Dead Letter Channel) 147 Канал недоставленных сообщений (Dead Letter Channel) ШММШ Компания использует обмен сообщениями (Messaging, с. 87) для интеграции приложений. Что делать с сообщениями, которые не удается доставить? Если получатель принимает сообщение, но не может его обработать, он должен пере- местить его в канал недопустимых сообщений (Invalid Message Channel, с. 143). Но что делать, если система обмена сообщениями даже не может доставить сообщение получателю? Существует целый ряд причин, по которым сообщение не всегда удается доставить получателю. Канал обмена сообщениями может быть неправильно настроен. После от- правки сообщения (но еще до его доставки) канал могут внезапно удалить. Срок действия сообщения (Message Expiration, с. 198) может истечь еще до того, как сообщение будет достав- лено. Впрочем, даже если срок действия не указан явно, сообщение все равно может уста- реть, если не будет доставлено в течение слишком долгого времени. Если в заголовок сооб- щения вставлено значение выбора, которое проигнорируют все избирательные потребители (Selective Consumer, с. 528), сообщение никогда не прочтут, и оно в конце концов устареет. Наконец, успешной доставке сообщения могут помешать ошибки в полях заголовка. Как только система обмена сообщениями определит, что не может доставить сообще- ние, она должна решить, что с ним делать. Сообщение можно оставить там, где оно есть, но это приведет к “захламлению” системы. Можно попытаться вернуть сообщение от- правителю, но отправитель — не получатель и не сможет обнаружить, что ему доставили сообщение. Можно тихонько удалить сообщение в надежде, что никто не заметит его от- сутствия, но это, вероятно, станет проблемой для отправителя, который успешно отпра- вил сообщение и ожидает, что оно будет доставлено, получено и обработано. Способ функционирования канала недоставленных сообщений зависит от реализации конкретной системы обмена сообщениями. Иногда указанный канал называют “очередью недоставленных (или мертвых) сообщений” (dead message queue [27]) или “очередью недоставленных писем” (dead letter queue [7, 28]). Обычно у каждого компью- тера, на котором установлена система обмена сообщениями, есть собственный канал не- доставленных сообщений. По этой причине вне зависимости от того, на каком компьютере обнаружится недоставленное сообщение, оно будет перемещено из одной локальной очереди в другую, не рискуя потеряться при передаче по ненадежной сети. Система об- мена сообщениями зафиксирует, на каком компьютере было обнаружено недоставлен- ное сообщение, а также по какому каналу оно изначально должно было быть доставлено. Если система обмена сообщениями определяет, что не может или не должна доставить сообщение, его необходимо переместить в канал недоставленных сообщений (Dead Letter Channel).
148 Глава 4. Каналы обмена сообщениями сообщений Разница между недоставленным (dead) и недопустимым (invalid) сообщениями заклю- чается в следующем: недоставленное сообщение, как и следует из его названия, невоз- можно доставить получателю, а недопустимое сообщение успешно доставлено получате- лю, принято им, но не может быть обработано. Решение о том, следует ли отправить сообщение в канал недоставленных сообщений, принимается системой обмена сообще- ниями путем оценки заголовка. В отличие от этого отправку сообщения в канал недопус- тимых сообщений осуществляет получатель (из-за ошибок в теле сообщения, отсутствия интересующих его полей в заголовке и т.п.). Для получателя обнаружение и обработка недоставленных сообщений выглядит автоматизированным процессом, в то время как заниматься судьбой недопустимых сообщений должен он сам. Разработчик, использую- щий существующую систему обмена сообщениями, не может повлиять на то, как по- следняя обрабатывает недоставленные сообщения, но может внедрить собственный ме- ханизм обработки недопустимых сообщений (включая недоставленные сообщения, которые почему-то не были обработаны системой обмена сообщениями как таковые). Пример: торговля на бирже В системе биржевой торговли приложение, которое желает осуществить покупку или продажу, может отправить запрос на выполнение торговой операции. Чтобы гарантиро- вать, что запрос будет получен в рамках разумного лимита времени (скажем, не дольше чем через пять минут после отправки), срок действия сообщения (Message Expiration, с. 198) устанавливается равным пяти минутам. Если за это время сообщение не удалось доста- вить или же если приложение, выполняющее запросы на покупку/продажу, не смогло вовремя считать сообщение из канала, то сообщение изымается из канала запросов на выполнение торговых операций и помещается в канал недоставленных сообщений (Dead Letter Channel). Система биржевой торговли может осуществлять мониторинг канала недоставленных сообщений, чтобы вовремя узнавать о сорвавшихся торговых операциях.
Гарантированная доставка (Guaranteed Delivery) 149 Гарантированная доставка (Guaranteed Delivery) -------► 6 Компания использует обмен сообщениями (Messaging, с. 87) для интеграции при- ложений. Как гарантировать, что сообщение будет доставлено даже в случае сбоя системы обмена сообщениями? Одно из главных преимуществ асинхронного обмена сообщениями перед удаленным вызовом процедуры состоит в том, что отправитель, получатель и сеть, соединяющая их, не обязательно должны работать в одно и то же время. Если сеть недоступна, сообщение будет сохранено до тех пор, пока сеть вновь не начнет работать. Точно так же, если полу- чатель недоступен, система обмена сообщениями сохранит сообщение и будет пытаться доставить его до тех пор, пока получатель снова не станет доступным. Описанный про- цесс, лежащий в основе обмена сообщениями, носит название передача с промежуточ- ным хранением (store-and-forward). Так где же хранится сообщение прежде, чем продол- жить свой путь? По умолчанию система обмена сообщениями хранит сообщение в памяти до тех пор, пока оно не будет успешно передано в следующий пункт хранения. Такая схема успешно функционирует при условии, что система обмена сообщениями исправна. Но если по- следняя выходит из строя (например, из-за того, что один из ее компьютеров внезапно отключился от электросети, или по причине аварийного завершения процесса обмена сообщениями), сообщения, хранившиеся в памяти, будут потеряны. Большинство приложений сталкиваются с аналогичными проблемами. При неожи- данном отказе приложения данные, хранившиеся в памяти, исчезают. Для предотвраще- ния этой проблемы приложения используют файлы и базы данных, которые записыва- ются на диск, благодаря чему безболезненно переживают сбой приложения. Подобный способ хранения данных на случай отказа нужен и системам обмена сообщениями. Используйте гарантированную доставку (Guaranteed Delivery), чтобы разместить приложения в постоянном хранилище данных и избежать их потери в случае отказа системы обмена сообщениями. Компьютер 1 Компьютер 2
150 Глава 4. Каналы обмена сообщениями Согласно концепции гарантированной доставки система обмена сообщениями поме- щает сообщения во встроенное хранилище данных. У каждого компьютера, на котором установлена система обмена сообщениями, имеется собственное хранилище данных, чтобы сообщения хранились локально. Когда отправитель отсылает сообщение, опера- ция отправки не считается успешно завершенной до тех пор, пока сообщение не будет надежно сохранено в хранилище данных отправителя. Аналогичным образом сообщение не будет удаляться из указанного хранилища, пока не будет успешно передано и сохране- но в следующем хранилище, и т.п. Итак, с момента отправки сообщение всегда будет храниться на диске как минимум одного компьютера до тех пор, пока не будет успешно доставлено получателю и принято им. Наличие постоянного хранилища увеличивает надежность, но приводит к снижению производительности. Если потеря сообщений из-за отказа системы обмена сообщениями не так уж и важна, от гарантированной доставки лучше отказаться — так сообщения будут доходить намного быстрее. Не следует забывать и о том, что реализация гарантированной доставки в системах с высоким уровнем трафика может потребовать огромного количества дискового про- странства. Если поставщик генерирует по нескольку сотен или тысяч сообщений в се- кунду, тогда даже несколько часов простоя сети приведут к неуемному потреблению мес- та на жестких дисках. Поскольку сеть недоступна, сообщения должны сохраняться на локальном жестком диске компьютера, на котором установлен поставщик. Но этот диск вряд ли рассчитан на хранение такого гигантского объема данных. По этой причине в не- которых системах обмена сообщениями разрешается настраивать таймаут повторных попыток (retry timeout). Данный параметр задает, сколько времени сообщение будет хра- ниться в системе обмена сообщениями. В некоторых приложениях с интенсивным тра- фиком (например, передающих биржевые котировки в режиме реального времени) зна- чение тайм-аута может равняться всего нескольким минутам. К счастью, большинство таких приложений генерируют сообщения о событиях (Event Message, с. 174), которые можно безбоязненно отбросить через короткий промежуток времени. Более подробно об этом будет идти речь в разделе, посвященном сроку действия сообщения (Message Expiration, с. 198). Гарантированную доставку также рекомендуется отключать на время тестирования и отладки. Тогда для полной очистки каналов будет достаточно остановить и перезапустить сервер обмена сообщениями. Сообщения, стоящие в очереди и после перезапуска серве- ра, могут сильно затруднить отладку даже простых программ для обмена сообщениями. Пусть, к примеру, отправитель и получатель соединены каналом “точка-точка” (Point-to- Point Channel, с. 131). Если после перезагрузки сервера в канале все еще будет храниться старое сообщение, получатель обработает его раньше, чем какие-либо новые сообщения, отосланные отправителем. Это один из распространенных “подводных камней”, с кото- рыми сталкиваются отладчики систем асинхронного обмена сообщениями с гарантиро- ванной доставкой. Во многих коммерческих реализациях систем обмена сообщениями разрешается очищать отдельные очереди, чтобы во время тестирования обмен сообще- ниями было легче начать “с нуля”. (См. также раздел, посвященный вентилю канала (ChannelPurger, с. 579).)
Гарантированная доставка (Guaranteed Delivery) 151 Насколько надежна гарантированная доставка сообщений Важно помнить, что надежность компьютерных систем измеряется количеством “девяток”, например 99,9%. Иными словами, достичь 100-процентной надежности вряд ли вообще возможно, а повышение уровня надежности хотя бы на одну “девятку” (с 99,9% до 99,99%) приведет к непомерно резкому возрастанию стоимости системы. Указанное утверждение справедливо и для гарантированной доставки (Guaranteed Delivery). Всегда возможен сценарий, при котором сообщение все равно будет потеря- но. К примеру, если жесткий диск, на котором хранятся сообщения, выйдет из строя, сообщения будут уничтожены. Для повышения надежности дискового хранилища можно воспользоваться избыточным массивом дисков (RAID или др.). Тогда к уровню надежности, вероятно, добавится еще одна “девятка”, но достичь ста процентов все равно не удастся. Кроме того, если сеть будет недоступна на протяжении долгого вре- мени, сообщения могут заполнить собой жесткий диск компьютера, что приведет к невозможности записи новых сообщений. Таким образом, гарантированная достав- ка направлена на защиту системы обмена сообщениями от потенциальных простоев (таких, как сбой компьютера или сети), но, несмотря на свое название, полной гаран- тии все же не дает. В реализации MSMQ для .NET, чтобы содержимое канала сохранялось на диске, канал нужно объявить транзакционным. Это означает, что отправители сообщений, как правило, должны быть транзакционными клиентами (Transactional Client, с. 498). В JMS применение гарантированной доставки к каналу “публикация-подписка” (Publish-Subscribe Channel, с. 134) гарантирует лишь то, что сообщения будут доставлены активным подписчикам. Чтобы со- общения гарантированно доставлялись даже тогда, когда подписчик неактивен, последнему необходимо быть постоянным подписчиком (Durable Subscriber, с. 535). Пример: торговля на бирже В системе биржевой торговли запросы на осуществление торговых операций и подтвер- ждения операций разумно отправлять с использованием гарантированной доставки (Guaranteed Delivery), чтобы они не потерялись. Оповещения об изменении адреса также следует отправлять с использованием гарантированной доставки, а вот для обновлений биржевых котировок это не обязательно. Если обновление котировок потеряется, осо- бого вреда это не нанесет, а поскольку котировки обновляются весьма часто, размещение их в постоянном хранилище сделает гарантированную доставку неприемлемой в плане производительности и расходования ресурсов. В примере системы биржевой торговли из раздела, посвященного постоянному под- писчику (Durable Subscriber, с. 535), говорится, что некоторые подписчики данных об из- менении котировок могут захотеть стать постоянными. В этом случае канал данных об изменении котировок, вероятно, также должен обеспечивать гарантированную доставку. Но как при этом удовлетворить нужды подписчиков, которые не желают быть постоян- ными или не хотят страдать от снижения производительности, вызванного гарантирован- ной доставкой? Для решения этой проблемы рекомендуем создать два канала, по кото- рым будут рассылаться обновления котировок: один с гарантированной доставкой, а другой— без нее. На первый канал должны подписываться только те приложения, которым нужны абсолютно все обновления котировок, и их подписка должна быть по-
152 Глава 4. Каналы обмена сообщениями стоянной. Из-за повышенной нагрузки на канал с гарантированной доставкой издатель может отправлять обновления не так часто, как по второму каналу. (См. также стратегию канала качества обслуживания в разделе, посвященном каналу типа данных (Datatype Channel, с. 139).) Пример: постоянные сообщения (JMS) Спецификация JMS разрешает задавать необходимость гарантированной доставки (Guaranteed Delivery) для отдельных сообщений. Иными словами, одни сообщения в ка- нале могут быть постоянными, а другие — нет [14,17]. Если отправитель хочет сделать сообщение постоянным, он должен воспользоваться своим объектом Messageproducer, чтобы изменить значение свойства JMSDeliveryMode указанного объекта сообщения на persistent. Это делается следующим образом. Session session = // Получить сеанс. Destination destination = // Получить пункт назначения. Message message = // Создать сообщение. MessageProducer producer = session.createProducer(destination); producer.send( message, j avax.j ms.De1iveryMode.PERSISTENT, javax.jms.Message.DEFAULT_PRIORITY, j avax.jms.Message.DEFAULT_TIME_TO_LIVE); Если постоянными должны быть все сообщения, которые отправляются приложени- ем, можно сделать так, чтобы при отправке сообщения поставщик MessageProducer по умолчанию применял режим persistent. producer.setDeliveryMode(j avax.jms.Delivery-Mode.PERSISTENT); (Вообще-то, стандартным режимом доставки для MessageProducer и так является persistent.) Теперь все сообщения, отправляемые указанным поставщиком сообще- ний, автоматически будут постоянными. Поэтому для отправки последующих сооб- щений достаточно просто воспользоваться методом send. producer.send(message); Вместе с тем сообщения, отправляемые по этому же каналу другими поставщиками, могут быть или не быть постоянными. Все зависит от того, как у них настроен режим доставки сообщений. Пример: IBM WebSphere MQ В системе обмена сообщениями IBM WebSphere MQ гарантированную доставку (Guaranteed Deliveiy) можно определять как для всего канала, так и для отдельных сооб- щений. Если канал не является постоянным (в том смысле, что его содержимое не сохра- няется на постоянном носителе), сообщения не могут быть постоянными. Если же канал
Гарантированная доставка (Guaranteed Delivery) 153 постоянный, его можно настроить так, чтобы все отправляемые по нему сообщения автоматически делались постоянными (или же чтобы каждое отдельное сообщение по желанию отправителя могло быть постоянным либо не постоянным). Канал определяется как постоянный (или не постоянный) во время его создания в системе обмена сообщениями. Если настроить канал так, как показано ниже, все от- правляемые по нему сообщения будут постоянными. DEFINE Q(myQueue) PER(PERS) А вот как настроить канал, чтобы необходимость гарантированной доставки сообще- ния задавалась самим отправителем. DEFINE Q(myQueue) PER(АРР) В последнем случае режим доставки сообщения может задаваться с помощью JMS-объекта Messageproducer, как показано в предыдущем примере. Если же канал на- строен таким образом, что все отправляемые по нему сообщения автоматически становятся постоянными, тогда параметры режима доставки, заданные объектом Messageproducer, будут игнорироваться [47]. Пример: постоянные сообщения (.NET) В .NET для получения постоянных сообщений необходимо создать транзакционную очередь сообщений. MessageQueue.Create("MyQueue", true); Сообщения, отправляемые через такую очередь, автоматически становятся постоян- ными [7].
154 Глава 4. Каналы обмена сообщениями Адаптер канала (Channel Adapter) Многие компании применяют обмен сообщениями (Messaging, с. 87) для интеграции неоднородных, часто изолированных приложений. Как подключить изолированное приложение к системе обмена сообщениями, чтобы оно могло отправлять и получать сообщения? Большинство приложений, используемых в крупных компаниях, не предназначались для работы с инфраструктурой обмена сообщениями. На это есть масса причин. Многие приложения изначально разрабатывались как самодостаточные, изолированные реше- ния, даже несмотря на то, что содержащиеся в них данные или функциональность могли бы быть задействованы другими системами. В качестве примера можно привести прило- жения для мэйнфреймов, которые, как предполагалось, никогда не будут “общаться” с другими приложениями. К сожалению, наличие унаследованных систем остается одной из наиболее распространенных проблем интеграции корпоративных приложений. Еще одна причина вытекает из того факта, что большинство связующего ПО, ориентиро- ванного на обмен сообщениями, взаимодействует с другими системами посредством соб- ственных, закрытых API. Как следствие этого разработчику приложения приходится пи- сать множество интерфейсов для работы с системами обмена сообщениями — по одному на каждого потенциального производителя связующего ПО. Приложения, которым нужно обмениваться данными с другими системами, часто ориентированы на использование более универсальных механизмов взаимодействия, таких как обмен файлами или работа с таблицами баз данных. Чтение и запись файлов являются базовыми функциями операционной системы и не зависят от специфических интерфейсов API того или иного производителя. Точно так большинство бизнес- приложений уже хранят свои данные в базе данных, поэтому им практически ничего не стоит поместить туда и данные, предназначенные для других систем. И наконец, при- ложение может предоставить доступ к своей функциональности посредством некоторого универсального интерфейса, который может использоваться в любой другой интеграци- онной стратегии, включая обмен сообщениями. Другие приложения могут иметь возможность взаимодействия по простому протоколу наподобие HTTP или TCP/IP. Указанные протоколы, однако, не столь надежны, как канал сообщений (Message Channel, с. 93), а формат данных, используемый для такого взаимодействия, специфичен для приложений и часто не совместим с форматом данных, который применяется системой обмена сообщениями. Если приложение написано разработчиками компании, к нему теоретически можно добавить код, который позволит приложению отправлять и получать сообщения. Но это может повысить сложность приложения, а также вызвать целый ряд “побочных” эффек- тов. Кроме того, разработчики должны быть знакомы как с логикой приложения, так и с интерфейсами обмена сообщениями. И разумеется, данный подход предполагает,
Адаптер канала (Channel Adapter) 155 что у компании имеется доступ к коду приложения. Если же оно было куплено у сторон- него производителя в готовом виде, внести изменения в его код, скорее всего, не удастся. Используйте адаптер канала (Channel Adaptef), который сможет осуществить дос- туп к интерфейсу API или данным изолированного приложения, создать на основе этих данных сообщение и разместить его в канале. Аналогичным образом адаптер канала может получать сообщения, а затем в зависимости от их содержимого вы- зывать в приложении ту или иную функциональность. Адаптер Сообщение канала Канал сообщений Адаптер канала выполняет роль клиента для системы обмена сообщениями и по ее требованию вызывает функции приложения через интерфейс последнего. Точно так он может наблюдать за событиями, происходящими внутри приложения, и в ответ на них вызывать систему обмена сообщениями. Благодаря такой схеме каждое приложение мо- жет взаимодействовать с системой обмена сообщениями, а следовательно, и интегриро- ваться с другими приложениями. Адаптер канала может подключаться к различным уровням архитектуры приложения (рис. 4.3). В зависимости от особенностей архитектуры и того, какие данные нужны сис- теме обмена сообщениями, выделяют несколько типов адаптеров. Рис. 4.3. Адаптер канала, подключенный к различным уровням архитектуры приложения
156 Глава 4. Каналы обмена сообщениями 1. Адаптер интерфейса пользователя. Адаптеры такого типа, метод работы которых иногда пренебрежительно называют “прочесыванием экрана” (screen scraping), эффективны во многих ситуациях. Пусть, к примеру, приложение реализовано на платформе, которая не поддерживается системой обмена сообщениями, или вла- делец приложения не слишком заинтересован в его интеграции. Это исключает возможность функционирования адаптера канала на платформе приложения. С другой стороны, пользовательский интерфейс таких приложений обычно дос- тупен с других машин и платформ (например, терминалов 3270). Кроме того, по- пулярность архитектуры “тонких клиентов” на основе Web привела к некоторому возрождению интеграции через интерфейс пользователя. Применение пользова- тельских интерфейсов, основанных на HTML, значительно облегчает создание HTTP-запроса и обработку результатов. Еще одним преимуществом интеграции на основе пользовательского интерфейса является отсутствие необходимости прямого доступа к внутренним механизмам приложения. Иногда предоставление доступа к внутренним функциям системы невозможно или нежелательно. Используя адаптер интерфейса пользователя, другие системы получат такой же доступ к приложению, как и обычный пользователь. Недостатком таких адапте- ров является потенциальная уязвимость и низкая скорость обмена данными. Приложение должно обработать данные, введенные “пользователем”, и визуали- зировать на экране соответствующее окно. Адаптер канала, в свою очередь, должен преобразовать содержимое этого окна обратно в необработанные данные. Этот процесс включает в себя много лишних шагов и выполняется довольно мед- ленно. Кроме того, пользовательские интерфейсы меняются гораздо чаще, чем логика приложения, а каждое изменение интерфейса пользователя влечет за со- бой необходимость соответствующего изменения адаптера канала. 2. Адаптер бизнес-логики. Большинство бизнес-приложений предоставляют доступ к своей функциональности через интерфейсы API (application programming interface — программный интерфейс приложения). Это может быть как набор компонентов (например, компоненты EJB, объекты СОМ, компоненты CORBA и т.п.), так и прямой программный интерфейс (библиотеки C++, C# или Java). Поскольку указанные интерфейсы специально предназначены для доступа других приложений, они обычно более стабильны, чем пользовательский интерфейс. В большинстве случаев доступ через API является и более эффективным. В общем случае, если приложение обладает нормальным интерфейсом API, наиболее предпочтительным решением будет именно данный тип адаптера канала. 3. Адаптер базы данных. Многие бизнес-приложения хранят свои данные в реляци- онной БД. Поскольку вся необходимая информация уже находится в базе данных, адаптер канала может извлекать ее оттуда, не вторгаясь в работу приложения. Это, пожалуй, наименее агрессивный способ интеграции приложений. Более то- го, адаптер канала может добавлять триггеры к интересующим его таблицам и от- правлять сообщения при каждом изменении данных в таблицах. Адаптеры такого типа достаточно эффективны и универсальны, учитывая и тот факт, что на рынке реляционных СУБД доминируют лишь два-три производителя. Это позволяет подключаться к самым разнообразным приложениям, используя относительно универсальный адаптер. Недостатком использования адаптера базы данных явля- ется глубокое вторжение в данные, используемые приложением. Это не так опас-
Адаптер канала (Channel Adapter) 157 но, если мы просто читаем данные, а вот запись обновлений прямо в базу данных, минуя приложение, — довольно рискованное занятие. Кроме того, многие про- изводители приложений оставляют за собой право изменять схему базы данных внезапно и по своему усмотрению. Из-за этого решения с адаптерами базы дан- ных крайне неустойчивы к изменениям. Говоря об адаптере канала, следует указать на важное ограничение: адаптеры канала могут преобразовывать сообщения в вызовы функций приложения, но для этого формат сообщений должен точно соответствовать реализации компонентов приложения, к кото- рым обращается адаптер. К примеру, адаптер базы данных обычно требует, чтобы имена полей во входящих сообщениях были такими же, как имена таблиц и полей в базе данных приложения. Такой формат сообщений полностью определяется внутренней структурой конкретного приложения и плохо подходит для обмена данными при интеграции с дру- гими приложениями. По этой причине большинство адаптеров канала приходится ком- бинировать с трансляторами сообщений (Message Translator, с. 115). Последние будут пре- образовывать сообщение из формата, специфичного для указанного приложения, в фор- мат, совместимый с канонической моделью данных (Canonical Data Model, с. 367). Адаптеры канала не обязательно должны работать на том компьютере, на котором на- ходится приложение или база данных. Адаптер канала может подключаться к логике приложения или базе данных через протоколы наподобие HTTP или ODBC. Это избав- ляет от необходимости устанавливать дополнительное ПО на сервере приложений или баз данных. С другой стороны, указанные протоколы не обеспечивают такое качество обслуживания, какое может предоставить канал обмена сообщениями (например, гаран- тированную доставку). По этой причине необходимо помнить о том, что удаленное со- единение с базой данных представляет собой потенциальную точку сбоя. Некоторые адаптеры канала являются однонаправленными. К примеру, если адаптер канала подключается к приложению через протокол HTTP, он, вероятно, сможет только потреблять сообщения и в ответ на них вызывать функции приложения. Распознавать непосредственные изменения в данных приложения и генерировать сообщения он вряд ли сможет (разве что только путем повторяющегося опроса, что весьма неэффективно). Существует интересная разновидность адаптера канала, называемая адаптером метаданных (Metadata Adapter) или адаптером времени разработки (Design-Time Adapter). Адаптер такого типа не вызывает функции приложения, а извлекает метаданные, описы- вающие внутренние форматы данных приложения. Извлеченные метаданные могут за- тем быть использованы для настройки трансляторов сообщений или для обнаружения из- менений в форматах данных, используемых приложением (см. раздел “Введение” гла- вы 8). Многие интерфейсы приложений поддерживают такую процедуру извлечения метаданных. К примеру, большинство коммерческих баз данных включают в себя набор системных таблиц, содержащих метаданные в виде описания таблиц приложения. Точно так большинство платформ компонентов (например, J2EE и .NET) обладают специаль- ными функциями “отражения” (reflection functions), которые позволяют компоненту получить сведения о методах, предоставляемых другим компонентом. Особой разновидностью адаптера канала является мост обмена сообщениями (Messaging Bridge, с. 159). Он соединяет систему обмена сообщениями не с конкретным приложением, как обыкновенный адаптер, а с другой системой обмена сообщениями.
158 Глава 4. Каналы обмена сообщениями Обычно адаптер канала реализуют в виде транзакционного клиента (Transactional Client, с. 498). Это гарантирует, что каждое действие адаптера будет успешно завершено как в системе обмена сообщениями, так и в системе, с которой та связывается при по- мощи адаптера. Пример: торговля на бирже Пусть система биржевой торговли ведет журнал котировок, оформив его в виде таблицы ба- зы данных. Тогда система обмена сообщениями может включать в себя адаптер реляцион- ной базы данных, который будет извлекать сообщения из канала и помешать данные о ко- тировках в указанную таблицу. Такой адаптер между каналом и реляционной СУБД будет представлять собой адаптер канала (Channel Adapter). Система также сможет получать внешние запросы о котировках из Интернета (по протоколам TCP/IP и HTTP) и пересы- лать их в виде внутренних запросов по своему внутреннему каналу запросов о котировках. Адаптер между Интернетом и внутренним каналом также будет адаптером канала. Пример: коммерческие ЕА1-средства Производители коммерческих EAI-средств часто включают в состав своих продуктов коллекцию готовых адаптеров канала (Channel Adapter) для популярных пакетов прило- жений. Наличие адаптеров значительно упрощает разработку интеграционных решений. Многие производители также оснащают свои продукты более универсальными адапте- рами базы данных и наборами средств для разработки ПО (software development kit — SDK), которые могут применяться для создания собственных адаптеров. Пример: адаптеры для унаследованных платформ Некоторые производители ПО выпускают адаптеры для связи популярных систем обме- на сообщениями с устаревшими системами, функционирующими на платформах UNIX, MVS, OS/2, AS/400, Unisys, VMS и т.п. Большинство таких адаптеров приспособлены под конкретную систему обмена сообщениями. К примеру, EnvoyMQ от компании Envoy Technologies — это адаптер канала (Channel Adapter), позволяющий соединять целый ряд унаследованных платформ со службой MSMQ. Он состоит из клиентского компонента, работающего на компьютере с унаследованной системой, и серверного компонента, ко- торый функционирует на компьютере Windows с установленной на нем службой MSMQ. Пример: адаптеры для Web-служб Многие системы обмена сообщениями содержат адаптеры канала (Channel Adapter) для обмена сообщениями SOAP с транспортом HTTP. Благодаря этому сообщения SOAP могут передаваться по интрасети с использованием надежной, асинхронной системы об- мена сообщениями, а также по глобальному Интернету (в том числе через брандмауэры) с использованием протокола HTTP. Примером такого адаптера является Web Services Gateway для IBM WebSphere Application Server.
Мост обмена сообщениями (Messaging Bridge) 159 Мост обмена сообщениями (Messaging Bridge) Компания использует обмен сообщениями (Messaging, с. 87) для взаимодействия между приложениями. К сожалению, в компании функционирует сразу несколько систем об- мена сообщениями. Это весьма затрудняет выбор системы, к которой необходимо под- ключить то или иное приложение. Как связать несколько систем обмена сообщениями, чтобы сообщения, переда- ваемые по одной из них, были доступны и в других системах? Распространенной проблемой интеграции корпоративных приложений является наличие в компании сразу нескольких систем обмена сообщениями. Они могут появить- ся в результате слияния или поглощения компаний, в каждой из которых применялась собственная система обмена сообщениями. Иногда компания, использующая некоторую систему обмена сообщениями для интеграции унаследованных систем (или приложений для мэйнфреймов), выбирает другую систему обмена сообщениями для своего сервера Web-приложений J2EE и .NET. В результате указанные системы приходится интегриро- вать. Еще один распространенный пример— это приложение, взаимодействующее с системами нескольких компаний, например В2В-клиент, желающий выступать в каче- стве покупателя в нескольких аукционных системах. Если в последних используются разные системы обмена сообщениями, приложение-покупатель может захотеть перено- сить сообщения, получаемые им в разных системах, в одну внутреннюю систему обмена сообщениями. И наконец, в качестве еще одного примера можно рассмотреть очень большую корпорацию с огромным числом каналов сообщений (Message Channel, с. 93) и конечных точек сообщения (Message Endpoint, с. 124). Такой корпорации может потребо- ваться несколько экземпляров системы обмена сообщениями, а значит, эти экземпляры надо как-то связать между собой. Пусть приложения некоторой компании используют две системы обмена сообщениями. Если сообщения одной системы не представляют никакого интереса для приложений, использующих другую систему, тогда обе системы могут оставаться полностью изолиро- ванными друг от друга. На практике, однако, чаще бывает наоборот: приложения, исполь- зующие одну систему обмена сообщениями, заинтересованы в том, чтобы передавать свои сообщения в другую систему обмена сообщениями (или получать их оттуда). Среди разработчиков весьма распространено заблуждение, что решить такую пробле- му можно с помощью стандартизированного интерфейса API для обмена сообщениями, например JMS. Это в корне неверно. С помощью JMS можно сделать так, чтобы две со- вместимые системы обмена сообщениями выглядели для клиентского приложения, как одна система, но никак нельзя обеспечить взаимодействие этих систем между собой. Что- бы системы обмена сообщениями работали друг с другом, они должны быть интеропера- бельными, т.е. использовать один и тот же формат сообщений, а также одним способом передавать сообщение из одного хранилища сообщений в другое. Но системы обмена со- общениями, созданные различными производителями, вряд ли будут интероперабель-
160 Глава 4. Каналы обмена сообщениями ними; прежде всего, потому, что хранилище сообщений одного производителя будет ра- ботать исключительно с хранилищами сообщений этого же производителя. Каждое приложение компании можно оснастить несколькими клиентами: по одному на каждую систему обмена сообщениями. Это, однако, повысит сложность приложений и степень дублирования на уровне обмена сообщениями. Избыточность такого решения становится особенно очевидной, если в компании появится еще одна система обмена сообщениями, и все существующие приложения понадобится снова модифицировать. С другой стороны, каждое приложение могло бы взаимодействовать только со своей сис- темой обмена сообщениями и игнорировать данные в других системах. Это упростит структуру приложения, но “отрежет” его от целого пласта корпоративных данных. Нам же требуется следующее: сделать так, чтобы данные из одной системы обмена сооб- щениями стали доступными для приложений, которые тоже интересуются указанными данными, но сами используют другую систему обмена сообщениями. Используйте мост обмена сообщениями (Messaging Bridge) как “связующее зве- но” между системами обмена сообщениями, которое реплицирует сообщения из одной системы в другую и наоборот. Система обмена Мост обмена Система обмена сообщениями 1 сообщениями сообщениями 2 Если рассматривать систему обмена сообщениями как единый, цельный объект, то связать между собой две такие системы не представляется возможным. Вместо этого мы по отдельности связываем канал одной системы и соответствующий ему канал другой системы. Мост обмена сообщениями— это набор адаптеров канала (Channel Adapter, с. 154), только в роли приложения, не имеющего возможности отправлять и получать со- общения, здесь выступает другая система обмена сообщениями, а каждая пара адаптеров связывает пару соответствующих каналов каждой из систем. Мост выступает в качестве преобразователя одного набора каналов в другой набор, а также преобразует сообщения из одного формата в другой. Каналы, связанные мостом, могут применяться как для передачи сообщений между обычными клиентами систем обмена сообщениями, так и строго для передачи сообщений в другие системы обмена сообщениями. Возможно, вам придется вручную реализовывать мост обмена сообщениями для своей компании. Мост — это специализированный вариант конечной точки сообщения (Message Endpoint, с. 124), являющийся клиентом обеих систем обмена сообщениями. Когда сообще- ние размещается в канале одной из систем, мост потребляет это сообщение, а затем отправ- ляет другое сообщение с таким же содержимым в соответствующий канал второй системы. Многие готовые системы обмена сообщениями обладают расширениями для связи с аналогичными системами других производителей. Благодаря этому мост часто можно купить, а не разрабатывать вручную.
Мост обмена сообщениями (Messaging Bridge) 161 Если другая “система обмена сообщениями” на деле является простым протоколом наподобие HTTP, воспользуйтесь шаблоном адаптер канала. Необходимость в наличии моста обмена сообщениями вызвана тем, что каждый произ- водитель систем обмена сообщениями имеет собственное видение того, как следует представлять сообщения и каким способом передавать их из одного хранилища в другое. Между тем для стандартизации указанных подходов можно было бы применять Web-службы. Передавая сообщения в соответствии со стандартами Web-служб, можно добиться того, чтобы две копии систем обмена сообщениями (даже от разных производи- телей) функционировали, как единое целое. Более подробно о стандартах WS-Reliability и WS-ReliableMessaging будет идти речь в главе 14. Пример: торговля на бирже У брокерской фирмы может быть система обмена сообщениями, которая применяется для передачи данных между ее различными офисами. У банка может быть другая система обмена сообщениями, используемая для взаимодействия между его отделениями. Пред- положим, что брокерская фирма и банк решили объединиться в компанию, которая будет предоставлять банковские и инвестиционные услуги. Какую из систем обмена со- общениями должна использовать новоиспеченная компания? Вместо того чтобы переде- лывать половину имеющихся приложений под использование другой системы обмена сообщениями, компания может воспользоваться мостом обмена сообщениями (Messaging Bridge), чтобы связать системы. С его помощью приложение банка и приложение брокер- ской фирмы могут согласовывать свои действия, чтобы, к примеру, перевести деньги с депозита на счет, предназначенный для оплаты торговых операц