Архивы: по дате | по разделам | по авторам

Часть IV.2. Межобъектная коммуникация на базе MSMQ

АрхивПрограммазм (архив)
автор : Юрий Кулешов   27.06.2001

Безопасное многопользовательское функционирование приложений, построенных на основе ЕСС и использующих MSMQ.

Итак, моя скромная кампания по агитации за переход на истинно распределённые системы практически завершена. Осталось лишь, как и обещано было, поделиться своими соображениями относительно того, как организовать совместную работу объектов на базе компонентных технологий Microsoft. Уже было рассказано ранее, для чего и как это может потребоваться. Пришло время демонстраций.

Что есть MSMQ

MSMQ (Microsoft Message Queue) — это всего лишь протокол, обеспечивающий передачу данных в распределённых приложениях данных на платформе Windows. В продуктах, представляющих собой распределённые приложения в стиле Windows, получили распространение 3 протокола: HTTP, DCOM и вот — MSMQ. «Зачем третий-то?» — спросите вы меня. Отвечу. Всё дело в том, что в целом ряде случаев требуется асинхронность в передаче данных от клиента к серверу и наоборот. Рассмотрим, такой пример: предположим, что в некоторой компьютерной сети установка локального времени производится, используя информацию с «сервера точного времени»: с некоторым интервалом сервер проводит опрос «живых» станций и сообщает им, что они должны провести синхронизацию времени (поверка, проще говоря). Это обычный сценарий — что-то вроде переклички. «Живой», то есть работающий и отвечающий на запросы, компьютер, получая требование о переводе времени «берёт под козырёк» и приводит своё время в соответствие с присланным с сервера. Но что произойдёт в том случае, когда компьютер отключен? Многие пользователи выключают «процессоры», уходя домой. Неужели сервер будет ломиться к ним, пока не наступит утро, и компьютеры снова не включат? Звучит несколько безумно, не правда ли? В том случае, когда мы используем синхронные протоколы, нам приходится идти на всевозможные ухищрения, вроде установки времени таймаута и проч. в том же духе. Но что делать, если время вышло, а сообщение об изменении времени не доставлено? Ведь «завтра с утра» эта машина может иметь неверно установленное время! В ряде случаев эта ситуация убийственна! А представьте себе ещё такую ситуацию: отключив на ночь телефон, вы утром не обнаруживаете важнейшего сообщения (которое точно было вам отправлено!), просто потому, что сервис-центр решил, что раз уж трубка не отвечала час, то ей и вовсе незачем что-то передавать. Это не какой-то там компьютер с неточным временем, тут что-то надо делать.

А делать здесь нужно вот что: использовать MSMQ. Очереди сообщений хороши тем, что имеют очень и всем привычную метафору: письма до востребования, или наша обычная электронная почта, e-mail. В самом деле, кто-то присылает нам сообщение, но прочитать его нельзя до тех пор, пока у нас не будет запущен почтовый клиент (некоторые читают почту с помощью telnet, зрелище жутковатое) и мы не загрузим сообщение с сервера. MSMQ, говоря общо, состоит из трёх базовых компонентов:

  • очередей, в которые клиент может направлять свои сообщения
  • самих сообщений
  • средств манипулирования объектами MSMQ, или API

Сам же процесс работы с применением MSMQ выглядит так:

  1. Кто-то создаёт очередь сообщений (администратор или приложение)
  2. Клиент создаёт сообщение, устанавливает его атрибуты и посылает его в эту очередь
  3. MSMQ устанавливает сообщение в очередь и немедленно (вот она, асинхронность!) возвращает управление клиенту
  4. Сервер очередей, определив, что в некую очередь пришло сообщение, считывает его и если требуется подтверждение, высылает его отправителю

Уже видно (п.3), что асинхронность увеличивает производительность. Однако, MSMQ позволяет большее! Можно слать запросы на обработку серверу даже в том случае, когда физическое соединение с ним отсутствует: сообщения будут помещены в локальную очередь на той машине, на которой работает приложение, а когда компьютер подключится к сети, данные будут переданы в «главное» хранилище.

Что делать?

Моё предложение по использованию MSMQ в деле коммуникации объектов заключается в следующем: все объекты класса должны иметь возможность своевременно узнавать об изменениях, вносимых в данные другими объектами своего класса (или того класса, который также может менять интересующие данные). А всякое изменение интересующих данных должно вызывать некое событие внутри заинтересованного объекта. Внутри же кода этого события и должно происходить решение извечного вопроса: «Данные изменились, и что делать?». Впрочем, это из другой оперы — один разработчик сказал мне буквально: «Что сделать-то я придумаю, ты скажи, как узнать, уже пора что-то делать?!» Что я могу на это сказать? Приходится повторяться! MSMQ! Вот сценарий в простейшем случае:

  1. Пользователь объекта Class изменяет его внутреннее состояние
  2. Код изменения состояния (свойства) помещает в очередь-источник сообщений (MSMQQueue) сообщение о том, что его данные изменились
  3. Объект MSMQEvent, прикреплённый к очереди-приёмнику в другом объекте Class получит событие, уведомляющее об изменении в каком-то объекте. В коде обработки этого события и нужно производить синхронизацию данных.

Посмотрите на простейший код (здесь и далее при нажатии на ссылку откроется новое окно с кодом программы — прим.ред.), раскрывающий основные моменты этой заметки.

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

Осталось показать лишь объект, используемый внутри классов ECC, и служащий для обеспечения межобъектной коммуникации.

QCore

Единственное назначение этого объекта — организовать «незаметную» работу с сервером очередей и максимально упростить задачу передачи сообщений об изменениях состояний объектов внутри окружения некой реализации ECC. Впрочем, никакой прямой привязки к ECC здесь нет и быть не может. Просто я говорю, что этот механизм можно использовать в рамках ECC. То, что здесь предлагается даже не является наиболее эффективной реализацией, но для целей иллюстрации концепций вполне подойдёт.

А теперь посмотрите на код, использующий предлагаемый объект.

Попробуйте запустить 2 копии этого примера и посмотрите, что будет происходить во втором приложении при отправке сообщений из первого (или наоборот).

Заключение

Хоть рассказано здесь и немного, но я всегда считал, что главное в работе — получить вектор. Думаю, что этот самый вектор статьи, в общем, задают. Если кому-то по прочтении этой, более чем месячной эпопеи покажется, что что-то, о чём я говорил можно сделать более эффективно и этот человек решит поделиться со мной, — буду только рад.

© ООО "Компьютерра-Онлайн", 1997-2024
При цитировании и использовании любых материалов ссылка на "Компьютерру" обязательна.