Tag Archives: Integration

EDI стандарт. Технический обзор

Разместил на habrahabr.ru статью «EDI стандарт. Технический обзор«.

В последнее время интерес к EDI в России возрос. Думаю, что это связано с внедрением больших ERP систем, таких, как SAP/R3, Peoplesoft, Oracle. Наши компании становятся публичными и их акции продаются на биржах. Многие биржи требуют, чтобы отчетность компаний удовлетворяла международным стандартам. А это подталкивает к уходу от программ уважаемой компании 1С к использованию ПО, которое знакомо и понятно международным аудиторам. И такая цепочка событий выводит нас на стандарт EDI.

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

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

 

Оставьте комментарий

Filed under EDI, Integration Architecture

Лучший Сервер приложений от Microsoft

Рассмотрим разные типы приложений.

Приложение для последовательной обработки

Приложение этого типа однопотоковое. Приложение получает массивы данных  и обрабатывает их одно за другим. BatchProcessing

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

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

Приложение – сервис

Программа-сервис постоянно ожидает запрос от клиента.  Если одновременно поступает много запросов, они ставятся в очередь на обработку. ShortRunningTransactions

Типичный представитель приложений этого класса – веб-сайт. Сервер приложений этого типа – Internet Information Server (IIS). Для каждого пользовательского запроса запускаеся отдельный процессорный поток, который завершается после выдачи результата пользователю. Если в приложении для последовательной обработки всегда работает только одна копия приложения, то здесь работают сразу несколько копий сервиса, по одной на каждый пользовательский запрос.  Обычно приложение не хранит данные клиента. Если по какой-то причине копия сервиса завершает работу с ошибкой и клиент не получает результат, клиент просто повторяет запрос и запускается другая копия сервиса. Данные хранит клиент, а не сервис. Сравним приложение-сервис с приложением для последовательной обработки. Последнее может обрабатывать только одну порцию данных одновременно. Кроме того обработка в нем не изолирована в отдельных копиях, и ошибка в обработке приведет к краху не одной копии, как в приложении-сервисе, а краху всего приложения. Надежная работа приложения-сервиса возможна тогда, когда приложение выполняет свою работу за короткое время. Если это время составляет часы и дни, то многократно возрастает возможность сбоя сервера приложения, соответственно уменьшается надежность тех копий приложения, которые во время краха находятся в памяти.

Приложение – долгоживущий сервис

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

LongRunningTransactions

Другая проблема долгоживущих сервисов – корреляция запросов.

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

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

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

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

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

  • хранилище данных копий сервисов;
  • системе корреляций запросов;
  • системе мониторинга и удаления «умерших» копий сервисов;
  • системе повтора запросов внишним сервисам

Как оказалось в арсенале Microsoft есть сервер приложений с подобными функциями. Это BizTalk Server.

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

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

Постоянно «измеряется пульс» и производится очистка памяти от «умерших» или завершенных копий сервисов.

Система вывода обеспечивает автоматическое повторение запросов внешним сервисам.

И самое главное качество BizTalk Server в качестве сервера приложений, это его надежность. Запущенные сервисы работают годами без присмотра. Пропадает электричество, «падают» сервера, пропадает сеть, ломаются жесткие диски. Но данные не пропадают. BizTalk автоматически перезапускается, прерванные сотни, тысячи копий сервисов восстанавливаются и продолжают работать как ни в чем ни бывало. Для этого работа в BizTalk Server элементарно распределяется между несколькоими компьютерами, а данные хранятся в SQL кластерах.

Оставьте комментарий

Filed under BizTalk, Integration Architecture, Microsoft

BizTalk: Соглашения об именах в примерах

Вначале можно ознакомиться со статьей BizTalk: BizTalk Solution Naming Conventions.

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

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

Документированные Соглашения об именах важны, но реальный код не менее важен. Документация может устареть, код всегда актуален. И код более нагляден.

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

Описание примера

Этот BizTalk код состоит из многих BizTalk приложений (applications). Каждое из приложений состоит в свою очередь из 1-10 Visual Studio проектов (projects). Эти приложения были разработаны в течении многих лет разными группами разработчиков. Приложения интегрируют несколько систем. Некоторые системы имеют только один интерфейс, некоторые — несколько интерфейсов. В большинстве случаев интерфейс одной системы интегрирован с интерфейсом другой системы. Иногда несколько систем интегрированны с одним интерфейсом системы.

Для этого примера было выбрано одно приложение (solution) . Еще раз акцентирую, это приложение из реальной жизни. Почему это приложение, GLG.Samples.Name.Shared.Schemas, было создано в данной ситуации? 

Как известно, интерфейсы в BizTalk определяются с помощью протокола и одной или нескольких XML cхем (schemas). Во многих случаях эти схемы диктуются самими интегрируемыми системами, а не разработчиками приложений. Обычно разработчик использует Adapter Wizard, чтобы сгенирировать/импортировать эти схемы. Эти схемы определяются и при необходимости меняются не разработчиками BizTalk приложения, а создателями и хозяевами интегрируемых систем. В дальнейшем такие схемы я буду называть внешними (external schemas).

Одна из интересных характеристик внешних схем то, что они могут использоваться несколькими BizTalk приложениями. Я однажды уже писал, что схемы, используемы в портах, должны быть уникальными (receive locations should be unique), они не могут содержаться одновременено в нескольких установленных библиотеках (deployed assemblies). Это означает, что если нам надо использовать одну и ту же схему в нескольких проектах, мы должны установить одну общую (shared) библиотеку один раз, не больше, и ссылаться на нее из всех этих проектов. 

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

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

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

Викторина 🙂 по деталям реализации:

  1. Нормально ли, когда имена скомпонованы из четырех и даже более частей, наподобие GLD.Samples.Names.Shared.Schemas?
  2. Необходим ли GLD.Samples префикс для имен BizTalk приложений?
  3. Почему мы используем суффикс _Ops в именах проектов SystemA, SystemB, и SystemC?

(Попытайтесь ответить на эти вопросы самостоятельно. Я дам мои ответы в конце статьи.)

В данном примере рассмотрены два варианта Соглашений об именах. Я назвал их Длинные имена и Короткие имена.

Длинные имена

Картинка из Solution Explorer (все картинки взяты из BizTalk Server 2013):

Solution.Long

Это картинка папок:

Folders.Long

Короткие имена

Это картинка из Solution Explorer:

Solution

Это картинка папок:

Folders

Сравнение соглашений

Соглашение Короткие Имена выглядит изящнее. Здесь нет общих префиксов (GLD.Samples.Names.Shared.Schemas) внутри имен проектов и файловых папок. Если вы сражаетесь с хорошо известным ограничением Visual Studio TFS на общий размер имен файлов, это соглашение будет предпочтительным вариантом.

Я предпочитаю Длинные Имена (Полные имена). В этом случае имена проектов абсолютно такие же как .NET namespace у этих проектов и такие же, как имена билиотек (assembly). Полные имена проектов лучше в ситуациях, когда имена проектов могут быть включены одновременно в несколько Visual Studio приложений (solutions) или когда приложения часто перемещаются между приложениями. Срабатывает закон KISS (keep it simple stupid). В данном случае соглашение Длинные имена позволяет обходиться одним соглашением для многих объектов. Закон KISS неимоверно важен в больших проектах. Простота обходится дорого, сложность рождается бесплатно. За простоту приходится сражаться. В данном случае наблюдается некий пародокс, простота достигается не короткими именами, а длинными.

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

Имена BizTalk приложений (Applications)

Это картинка Административной Консоли (BizTalk Administration Console):

BizTalkAdminConsole

Вы видите Visual Studio приложение (solution) GLD.Samples.Names.Shared.Schemas установлено (deployed) как  Names.Shared.Schemas приложение (application). Префикс GLD.Samples удален, так как все устновленные VS приложения используют этот префикс. Если все артифкты используют одну и ту же часть имени, эта часть совершенно однозначно может быть удалена. Не должна быть удалена, а может быть удлалена. Возникает вопрос, почему эта часть не удалена из имени приложения/проекта (solution/project)? Причина в том, что проекты и assemblies практически всегда именуются одинаково. Но assemblies работают в одном глобальном пространстве имен вместе с system, Microsoft и другими assemblies, в едином пространстве имен .NET run-time. В этом глобальном пространстве имен префикс GLD.Samples помогает нам находить наши assembles. Получается, что глобальное пространство имен assemblies вынуждает нас использовать этот префикс, что, в свою очередь, вынуждает нас использовать этот префикс для имен проектов. Это и есть обещанный ответ на второй вопрос. Smile

В результате я использовал соглашение с Короткими именами для имен BizTalk приложений. 

Насколько сложной может быть иерархия имен?

Для примера возьму имя GLD.Samples.Names.Shared.Schemas.Sap.AV_CREDIT_STATUS_MODIFY. Не слишком ли оно сложное и длинное?

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

Иерархические соглашения об именах — короли в BizTalk разработке. Эти соглашения отражают группировку объектов. Иерархические соглашения работают хуже в тех областях, где объектов мало и они логически не связаны. Здесь лучше работают соглашения, основанные на ключевых словах (keys or tags).

Обычно мы видим такую картину:

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

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

Надеюсь, я ответил на первый вопрос.

Теперь ответ на третий вопрос. Сразу уточню, что этот вопрос относится только к BizTalk проектам.
Почему был использован суффикс _Ops для проектов SystemA, SystemB и SystemC?

 Например, почему было использовано имя GLD.Samples.Names.Shared.Schemas.SystemA.CreditCheck_Ops, а не имя GLD.Samples.Names.Shared.Schemas.SystemA.CreditCheck ?

Проблема с этим именем в том, что проект содержит схему с именем CreditCheck. Что плохого в этом, почему мы не не можем использовать одинаковое слово для части имени проекта и для схемы?

XML схема (XML schema) сериализуется в .NET класс и имя схемы сериализуется в имя класса. В результате мы имеем класс с полным именем (full qualified name) GLD.Samples.Names.Shared.Schemas.SystemA.CreditCheck.ChreditCheck. И когда мы компилируем проект мы получаем ошибку:

Error.SymbolXIsAlreadyDefined

Описание (description) ошибки могло бы быть чуть понятнее, что-нибудь типа: “symbol ‘GLD.Samples.Names.Shared.Schemas.SystemA.CreditCheck’ is already defined; the first definition is in assembly…”.

По какой-то причине .NET builder разбирает имена иногда слева направо, а иногда справа налево, что и приводит к подобным ошибкам.

Это деталь реализации, но мы вынуждены из-за нее изменить наше соглашение об именах. Имя схемы мы не можем изменить (это внешняя схема), а вот имя проекта мы изменить можем. Добавили _Ops (operations) и это разрешило конфликт одинаковых имен.

Выводы

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

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

Оставьте комментарий

Filed under BizTalk, BizTalk course, Integration Architecture

BizTalk: Synchronous pattern. Really?

Последнее время стало модно делать интеграцию в асинхронном стиле. Ничего не блокируется, а значит хорошо масштабируется.  И крайний случай асинхронного стиля – ESB, Enterprise Service Bus, когда все данные перемещаются асинхронно.

Круто.

А на другом конце спектра – point-to-point интеграция, точечная. По крайней мере, если вы спросите об этом архитектора, то ESB много лучше point-to-point. И одна из главных причин в том, что ESB – асинхронна по сути, а point-to-point обычно в видет request-response, синхронна. С тем, что ESB лучше point-to-point я не соглашусь, но разговор здсь не об этом.

Если посмотреть в Википедии, полазить по книжкам, то окажется, что точного понятия синхонности и асинхронности в отношении ИТ и обмена данными нет.

Классическое определиение синхронности мало что нам даст. Синхронность, это когда время в раздельных точках установлено одинаково. В одном месте 54 минуты, 44 секунды и 234234 мили-микро и т.д секунд и в другом в этот же момент времени часы покажут те же цифры.

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

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

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

Как обмен данными происходит в BizTalk? Как реализуются синхронные и асинхронные процессы в BizTalk?

В качестве примера возьмем типичную задачу по интеграции двух систем, так называемый request-response. Одна система (А) запрашивает данные у другой системы (В). А посылает запрос в систему В, В обрабатывает данные и высылает результат обратно системе А.

На первый взгляд перед нами point-to-point интеграция, синхронный процесс. Так ведь?

А теперь подробнее.

BizTalk приемный порт (receive port) запускает процесс при появлении данных по адресу порта. Порт играет роль listener-а. Порт запускает отдельный message процесс под каждый запрос. Этот процесс обрабатывает запрос и записывает его в Почтовый Ящик (MessageBox) BizTalk.  Почтовый Ящик представляет из себя SQL Server базу данных, а с точки зрения системы по обработки сообщений он представляет из себя систему очередей. Почтовый Ящик – это сервер очередей сообщений. Send port (порт отправки) системы В является подписчиком для запросов из системы А. Запросы эти он получает из Почтового Ящика.  Порт получает новый запрос, после чего отправляет этот запрос в систему В и получает обратно ответ. Порт записывает ответ в Почтовый Ящик BizTalk. Приемный порт системы А является подписчиком для данного ответа. Он получает ответ из Почтового Ящика и отправляет его в систему А.

Таким образом данные два раза проходят через Почтовый Ящик. Сначала запрос, потом ответ.

Самое интересное в этом – очереди. Очереди по своей сути асинхронны.  Запрос и ответ не передаются в рамках одной сессии. Создаются от двух до четырех сессий: система А – приемный порт для запроса, порт отправки – система В для запроса, система В – порт отправки для ответа, приемный порт – система А для ответа. В зависимости от транспортного протокола сессии для запроса и ответа могут быть в рамках одной сессии, к примеру для HTTP протокола.

Любая передача сообщений через BizTalk асинхронна.

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

В рассмотренном примере с точки зрения системы А передача данных, запрос и ответ, происходят в рамках одной сессии, передача выглядит синхронной. С точки зрения системы В передача данных тоже происходит в рамках одной сессии и также синхронно. На самом деле обе эти сессии замыкаются в рамках система – Почтовый Ящик.

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

Оставьте комментарий

Filed under BizTalk, Integration Architecture