Замечания по выпуску


17.5 Использование сценариев

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

17.5.1 Базовая передача сообщений

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

В простом сценарии Клиент A вызывает функцию MQSEND, чтобы отправить пользовательскую строку в местонахождение службы по умолчанию. Затем функции MQSeries выполняются в DB2 на сервере баз данных. Через некоторое время Клиент B вызывает функцию MQRECEIVE, чтобы принять сообщение, стоящее первым в очереди, заданной службой по умолчанию, и возвратить его клиенту. Для выполнения этой задачи DB2 снова вызывает функции MQSeries.

Клиенты баз данных могут пользоваться простой передачей сообщений рядом способов. Наиболее обычные варианты применения передачи сообщений:

Следующий сценарий по сравнению с простым сценарием, описанным выше, дополнен удаленной передачей сообщений. Сообщение передается между компьютером A и компьютером B. Последовательность шагов следующая:

  1. Клиент DB2 вызывает MQSEND с указанием службы назначения, определенной для представления удаленной очереди на компьютере B.
  2. Функции DB2 MQSeries выполняют фактическую работу MQSeries, чтобы отправить сообщение. Сервер MQSeries на компьютере A принимает сообщение и гарантирует, что он доставит его в место назначения, заданное в определении точки службы и в текущей конфигурации компьютера A. Сервер определяет, что это - очередь на компьютере B. Затем он пытается отправить это сообщение серверу MQSeries на компьютере B, повторяя эти попытки при необходимости.
  3. Сервер MQSeries на компьютере B принимает сообщение от сервера на компьютере A и помещает в очередь назначения на компьютере B.
  4. Клиент MQSeries на компьютере B берет сообщение, стоящее первым в этой очереди.

17.5.2 Отправка сообщений

С помощью MQSEND пользователь или разработчик прикладных программ DB2 выбирает, какие данные отправить, куда их отправить и когда они будут отправлены. Такая ситуация обычно называется "отправить и забыть", то есть отправитель просто посылает сообщение, полагаясь на гарантированные протоколы доставки MQSeries, обеспечивающие, что сообщение достигнет своего назначения. Это показано в следующих примерах.

Пример 4: Чтобы отправить пользовательскую строку в точку службы myplace с правилами highPriority, введите:

VALUES DB2MQ.MQSEND('myplace','highPriority','проверка')

Здесь highPriority - это правила, определенные в Репозитории AMI, которые задают для приоритета самый высокий уровень, а также могут настроить и другие опции качества обслуживания, например, срок действия.

В состав сообщения может входить любая разрешенная комбинация SQL и пользовательских данных. Сюда входят вложенные функции, операторы и преобразования типов. Например, если у нас есть таблица EMPLOYEE со столбцами LASTNAME, FIRSTNAME и DEPARTMENT типа VARCHAR, чтобы отправить сообщение, содержащее эту информацию для каждого сотрудника отдела 5LGA, нужно ввести:

Пример 5:

SELECT DB2MQ.MQSEND(LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT)
FROM EMPLOYEE
   WHERE DEPARTMENT = '5LGA'

Если в таблице присутствует также целочисленный столбец AGE, его можно включить так:

Пример 6:

SELECT DB2MQ.MQSEND(LASTNAME||' '||FIRSTNAME||' '||DEPARTMENT||' '||char(AGE))
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

И наконец, в следующем примере показано, как можно создать содержимое сообщения с использованием допустимого выражения SQL. Взяв вторую таблицу DEPT со столбцами varchar DEPT_NO и DEPT_NAME, можно отправить сообщение, содержащее столбцы LASTNAME и DEPT_NAME:

Пример 7:

SELECT DB2MQ.MQSEND(e.LASTNAME || ' ' || d.DEPTNAME) FROM EMPLOYEE e, DEPT d
   WHERE e.DEPARTMENT = d.DEPTNAME

17.5.3 Прием сообщений

Функции DB2 MQSeries позволяют либо получать, либо читать сообщения. Чтение отличается от приема сообщения тем, что чтение возвращает головное сообщение без удалении его из данной очереди, а при приеме сообщение удаляется из очереди. С использованием операции приема сообщение можно получить только один раз, а операция чтения позволяет получать одно и то же сообщение многократно. Это показано в дальнейших примерах:

Пример 8:

VALUES DB2MQ.MQREAD()

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

Пример 9:

VALUES DB2MQ.MQRECEIVE('Employee_Changes')

В этом примере показано, как сообщение можно удалить из начала очереди, заданной службой Employee_Changes, с использованием правил по умолчанию.

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

Пример 10:

SELECT t.* FROM table ( DB2MQ.MQREADALL()) t 

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

Пример 11:

SELECT t.MSG FROM table (DB2MQ.MQREADALL()) t

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

Пример 12:

SELECT t.MSG, e.LASTNAME
   FROM table (DB2MQ.MQREADALL() ) t, EMPLOYEE e
      WHERE t.MSG = e.LASTNAME

Пример 13:

SELECT COUNT(*) FROM table (DB2MQ.MQREADALL()) t

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

Пример 14:

CREATE VIEW NEW_EMP (msg) AS
   SELECT t.msg FROM table (DB2MQ.MQREADALL()) t

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

Пример 15:

CREATE VIEW NEW_EMP2 AS
   SELECT left(t.msg,18) AS LNAME, right(t.msg,18) AS FNAME
   FROM table(DB2MQ.MQREADALL()) t

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

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

Пример 16:

INSERT INTO MESSAGES 
   SELECT t.msg FROM table (DB2MQ.MQRECEIVEALL()) t

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

17.5.4 Возможности соединения программ друг с другом

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

В этом разделе мы обсудим некоторые сценарии интеграции программ и возможности их использования с DB2. Поскольку тема весьма широка, всестороннее обсуждение интеграции программ выходит за рамки этой работы. Поэтому остановимся на двух простых вопросах: взаимодействие требование/ответ, а также интегратор MQSeries и публикация/подписка.

17.5.4.1 Взаимодействие требование/ответ

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

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

Пример 17:

DB2MQ.MQSEND ('myRequester','myPolicy','SendStatus:cust1','Req1')

Этот оператор добавляет заключительный параметр Req1 в вышеуказанный оператор MQSEND, чтобы указать ID корреляции для требования.

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

Пример 18:

DB2MQ.MQRECEIVE('myReceiver','myPolicy','Req1')

Если программа, обслуживающая требование, занята, а реквестер выдает указанный выше оператор MQRECEIVE перед отправкой ответа, не будет найдено ни одного сообщения, удовлетворяющего данному ID корреляции.

Чтобы получить и требование службы, и ID корреляции, используется примерно такой оператор:

Пример 19:

SELECT msg, correlid FROM table (DB2MQ.MQRECEIVEALL('aServiceProvider',
'myPolicy',1)) t

Он возвращает от провайдера aServiceProvider сообщение и идентификатор корреляции первого требования.

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

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

17.5.4.2 Публикация/подписка

Простая публикация данных

Другой обычный сценарий в интеграции программ состоит в том, что одна программа уведомляет другие программы о представляющих интерес событиях. Этого легко добиться, послав сообщение в очередь, которую отслеживает другая программа. Содержание сообщения может быть заданной пользователем строкой или состоять из столбцов базы данных. Часто требуется просто послать сообщение; для этого используется функция MQSEND. Если такое сообщение необходимо послать одновременно нескольким получателям, можно воспользоваться средством интерфейса MQSeries AMI Список распределения.

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

Пример 20:

DB2MQ.MQSEND('interestedParties','интересная для всех информация');

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

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

  1. Администратор MQSeries конфигурирует возможности публикации/подписки интегратора MQSeries.
  2. Заинтересованные программы подписываются в пунктах подписки, определяемых конфигурацией MQSI, задавая по желанию интересующие их темы. Каждый подписчик выбирает подходящие темы; он может также использовать технику подписки на основе содержания, применяемую в MQSeries Integrator V2. Важно отметить, что программу подписки определяют очереди, представленные именами служб.
  3. Программа DB2 выпускает сообщение в точке службы Weather (Погода). В сообщении указывается, что идет дождь со снегом и тема Austin, тем самым подписчики оповещаются, что в Остине идет дождь со снегом.
  4. Механика реальной публикации сообщений осуществляется функциями MQSeries, предоставляемыми DB2. Сообщение отправляется интегратору MQSeries с использованием службы Weather.
  5. MQSI принимает сообщение от службы Weather, выполняет всю обработку, определяемую конфигурацией MQSI, и определяет, каким подпискам оно соответствует. После этого MQSI отправляет это сообщение в очереди подписчиков, которых оно интересует.
  6. Программы, которые подписались на службу Weather и зарегистрировали тему Austin, получат сообщение Дождь со снегом в своей службе приема.

Чтобы опубликовать данные с использованием всех умолчаний, не задавая тему, следует воспользоваться примерно таким оператором:

Пример 21:

SELECT DB2MQ.MQPUBLISH(LASTNAME||' '||FIRSTNAME||' '||DEPARTMENT||' '||char(AGE))
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

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

Пример 22:

SELECT DB2MQ.MQPUBLISH('HR_INFO_PUB', 'SPECIAL_POLICY', LASTNAME,
   'ALL_EMP:5LGA', 'MANAGER')
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Этот оператор выпускает сообщения для издательской службы HR_INFO_PUB с использованием правил обслуживания SPECIAL_POLICY. В сообщениях указывается, что тема отправителя - MANAGER. В строке темы показана возможность указания нескольких тем, разделенных двоеточиями ':'. В этом примере использование двух тем позволяет подписчикам для получения сообщений зарегистрировать тему ALL_EMP или только 5LGA.

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

Пример 23:

DB2MQ.MQSUBSCRIBE('aSubscriber', 'ALL_EMP')

После подписки программы сообщения с темой ALL_EMP будут отправляться в службу получателя, определенную службой подписчика. У программы может быть несколько одновременных подписок. Для сообщений, отвечающих подписке, можно пользоваться любой стандартной функцией получения сообщений. Например, если служба подписчика aSubscriber задает, что служба получателя - aSubscriberReceiver, тогда следующий оператор прочтет первое сообщение, не удаляя его:

Пример 24:

DB2MQ.MQREAD('aSubscriberReceiver')

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

Пример 25:

SELECT t.msg, t.topic FROM table (DB2MQ.MQRECEIVEALL('aSubscriberReceiver',5)) t

Для чтения всех сообщений с темой ALL_EMP можно применить средства SQL:

Пример 26:

SELECT t.msg FROM table (DB2MQ.MQREADALL('aSubscriberReceiver')) t
   WHERE t.topic = 'ALL_EMP'
Прим.:Важно понять, что если MQRECEIVEALL используется с ограничением, будет использована вся очередь, а не только сообщения с темой ALL_EMP. Вот почему табличная функция выполняется перед применением этого ограничения.

Если вы больше не нуждаетесь в подписке на конкретную тему, нужно явно отменить подписку, воспользовавшись таким оператором:

Пример 27:

DB2MQ.MQUNSUBSCRIBE('aSubscriber', 'ALL_EMP')

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

Автоматическая публикация сообщений

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

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

Пример 28:

CREATE TRIGGER new_employee AFTER INSERT ON employee REFERENCING NEW ASn
      FOR EACH ROW MODE DB2SQL
      VALUES DB2MQ.MQPUBLISH('HR_INFO_PUB&',  'NEW_EMP',
      current date || ' ' || LASTNAME || ' ' || DEPARTMENT)


[ Начало страницы | Страница назад | Страница вперед | Содержание | Индекс ]