В данной статье будет рассмотрен вопрос включения 1С в глобальные транзакции в рамках сервис-ориентированной архитектуры. Эта статья является продолжением статьи "Интеграция 1С с сервисной шиной OpenESB".
В данной статье будет рассмотрен, пример организации автоматизированного взаимодействия Business2Business при помощи шины сообщений ActiveMQ (реализация Java Message Service). Основное внимание будет уделено специфичным вещам, которые требуются при интеграции разнородных систем с помощью шины сообщений: промежуточной обработке и преобразованию сообщений, маршрутизации и вопросам безопасности.
В данной статье рассматривается пример интеграции 1С с шиной сервисов OpenESB, и в более широком смысле - встраивание 1С в сервис-ориентированную архитектуру.
Эти статьи писались по наработкам, которые были сделаны перед написанием одной распределенной системы для сети магазинов: как один из вариантов рассматривался свежий на тот момент 8.2 (само собой, с извращениями и не "по Радченко"), но в конечном счете здравый смысл победил и решили писать на банальной жабке (абсолютно правильно решили, кстати, скорость написания не сильно меньше, а технологичность и предсказуемость гораздо выше). Ну а наработки пошли в статьи....
Коллега, с которым мы это начинали делать, через один коммент выше, кстати (8).
Нет, такого примера у меня сейчас нет. Надо смотреть, что за WSDL генерит JBoss и избавляться от любых наворотов в нем, вроде включенного WS-Security, надо смотреть как в этом WSDL'е описаны сложные типы (они могут и в отдельном XSD быть) и пр.
Да и вообще, я бы на движок веб-сервисов 1С'а не сильно полагался - там даже относительно "взрослые" движки, вроде WCF/Metrо/Axis2/CXF между собой далеко не всегда дружат - попытки заставить работать CXF и WCF между собой с шифрованием и подписью закончились пару лет назад безрезультатно (у меня), хотя вроде и стандарт, и xml'ники правильные формируются, и шифруется/подписывается, и каждый из движков лично самого себя прекрасно понимает и расшифровывает...
В качестве иллюстрации того, что при желании схему можно закрутить как угодно: при некоторой степени извращенности можно собрать кластер для бедных, в виде фоновой службы запущенной на офисных компах, которая через специальные очереди (или еще как) выгребает код скрипта или готовую библиотеку с точкой входа, а потом обрабатывает сообщения-запросы в соответствии с загруженной логикой, потихоньку отъедая избыточную вычислительную мощность у секретарши Маши и кадровички Любы.
Пнул новый скрипт/библиотеку - изменил логику обработки. Маша выключила компьютер? Не страшно, ведь осталась Люба! Правда остается еще вопрос с источником данных, в него тоже можно упереться (производительность/блокировки).
Все хорошо в меру и шина сообщений имеет целый ряд ограничений и специфических приемов при построении той или иной схемы. По большей части они происходят из асинхронной природы очередей: отсутствует блокировка для ожидания ответа. Тут есть как плюсы, так и минусы: главный плюс - возможность отложенной асинхронной и параллельной обработки, минус - сложность получения привычного "синхронного поведения".
Например, вот так реализуется схема запрос-ответ (на примере JMS, оно мне роднее): http://eaipatterns.com/RequestReplyJmsExample.html. Там же вроде есть и полный список паттернов интеграции: http://eaipatterns.com/toc.html.
Надо сказать что далеко не всегда требуется передавать данные учетных систем, которые должны следовать строго непрерывно и в полном объеме, данные вполне могут иметь "срок годности" (http://docs.oracle.com/cd/E17802_01/products/products/jms/javadoc-102a/javax/jms/MessageProducer.html - методы xxxTimeToLive).
Конкретно в вашем случае:
1. Если просто распихивать сообщения push'ем по очередям, без учета режима активности клиентов, то да - это приведет к затариванию очереди.
2. Если же усложнить схему:
- клиент отправляет сообщение с запросом в одну из очередей, указав кто он, что ему нужно и куда отвечать (replyTo в JMS).
- на другой стороне обработчик не спеша по этому запросу собирает ответный пакет, при этом транзакция на чтение из очереди запросов = транзакции на работу с БД с данными = транзакции на отправку ответного пакета (конструкция либо дорабатывает до конца, либо откатывается назад к состоянию, когда сообщение с запросом все еще стоит в очереди), после чего ответный пакет готов к забору со стороны клиента.
- клиент в одной транзакции получает пакет из шины и приземляет его к себе.
- при возникновении ошибки клиенту отправляется сообщение с ошибкой, которое он должен обработать тем или иным способом.
И вот во втором варианте, как мне кажется, вполне можно использовать timeToLive, причем и на запрос и на ответ. Клиенту будет достаточно сохранить id исходного сообщения (или другой уникальный признак), а серверу - возвращать ответные пакеты с указанием этого исходного id (то, что в JMS называется correlationId). Таким образом, всегда будет возможность узнать в ответ на какой запрос пришел этот ответный пакет, а зная порядок id запросов всегда можно восстановить соответствие, просто используя фильтр для выборки сообщения с тем или иным значением поля:
или что-то типа такого. В случае выборки ответов в нужном порядке по id, отпадает необходимость в строго последовательной обработке запросов на стороне сервера: можно сделать несколько параллельно работающих обработчиков и, при желании, получить кластер из коробки разнеся их по разным машинам - любой из обработчиков обработает любое сообщение-запрос, а порядок ответов восстановится за счет того, что клиент будет запрашивать ответ по фильтрам, в порядке id запросов.
Если же клиент по каким-то причинам не заберет сообщения из очереди, они удалятся по таймауту, начиная с самого старого. В этом случае необходимо опять сделать запрос на получение данных. В итоге получится что-то типа:
клиент -> [очередь запроса] -> обработчик(и) запросов <-> БД (или другой источник данных)
клиент <- [очередь ответа/ошибки] <------------------
Из push'а схема превращается в асинхронный poll с самообслуживанием со стороны клиента (он сам изъявляет желание получить данные).
При такой схеме клиент может "мерцать" как ему угодно, к затариванию это не приведет. С другой стороны имеем асинхронность и параллельность обработки.
(11) Ну для меня это не вариант, потому что хочется чего-то большего да и с SOAP'ом проблем особых не возникало. Однако в твоем примере прежде всего заинтересовало то что он для 77, из описания не совсем понятно возможна ли передача произвольных аргументов, и, что самое интересное, возвращение произвольных значений. Халявной сериализации-то в 77 нету...
(63) Я бы еще понял, если бы они привязали это дело к количество поднятых контекстов (и это было бы логичным), но мультиплексирование и "в действительности одновременно работающих с системой" - это уже перебор, хотя бы потому, что с именно "системой" они могут и не работать.
А мне, например, вот эта конструкция кажется абсолютно безумной:
>В соответствии с действующим Лицензионным соглашением, использование программных или аппаратных средств, уменьшающих количество пользователей, которые имеют непосредственный доступ к "1С:Предприятию 8", не уменьшает количества требуемых лицензий. Организация должна приобрести Клиентские лицензии по количеству пользователей, в действительности одновременно работающих с системой "1С:Предприятие 8".
>уменьшающих количество пользователей, которые имеют непосредственный доступ к "1С:Предприятию 8
но
>в действительности одновременно работающих с системой "1С:Предприятие 8"
под последнюю формулировку можно подогнать что угодно - это как если бы MS брала деньги не за клиентское подключение, а за всех, кто посмотрит потом отчет, выгруженный из базы через это подключение
хм... а если выгрузить в xls отчет из 1С и раздать его сотне человек - сколько потребуется лицензий? а если я напишу затычку, которая будет через одно COM-соединение вытаскивать данные и класть их в ОТДЕЛЬНУЮ БД (не 1C), к которой потом будет обращаться сайт со 100 пользователями в секунду? а в чем разница с отчетом? а является ли такая система средством уменьшающим количество пользователей? а если сделать асинхронную развязку (это к "в действительности одновременно"), когда часть которая общается с 1С, обрабатывает очередь запросов и приземляет их на 1С через ОДНО соединения? а если в эту очередь могут помещать данные разные удаленные системы? а если... о ужас - 1С по регламентному заданию будет класть в очередь сообщений данные, которые потом будут получать сразу 1000 подписчиков?
Я грешным делом думал, что непосредственно работают с системой = действительно работают с системой
а все кто опосредовано - работают уже с чем-то другим, и непосредственно с исходной системой не связаны и если это "что-то другое" обеспечивает мультиплексирование, то такова селява...