Решения для очереди сообщений? - PullRequest
2 голосов
/ 05 января 2010

(отредактировано, чтобы попытаться объяснить лучше)

У нас есть агент, написанный на C ++ для Win32. Необходимо периодически публиковать информацию на сервере. Он должен поддерживать отключенную операцию. То есть клиент не всегда имеет соединение с сервером.

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

Это означает, что сообщения, отправляемые на сервер, должны быть поставлены в очередь (чтобы их можно было отправлять, как только соединение будет доступно).

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

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

  1. Он должен быть доступен по умолчанию в Windows XP SP2, Windows Vista и Windows 7 или должен быть простым для включения в наш установщик. Этот продукт будет установлен (администраторами) на пару сотен тысяч ПК. Они, вероятно, будут использовать что-то вроде Microsoft SMS или ConfigMgr. В этом сценарии «несерьезные» предпосылки осуждаются. Это означает, что, если клиентский код (или распространяемый) не может быть включен в наш установщик, администратор не будет счастлив. Это делает MSMQ особенно трудным для продажи, потому что он не установлен по умолчанию с XP.

  2. Должно быть относительно простым в использовании из C ++ на Win32. Наш клиент - неуправляемое приложение C32 Win32. Нет .NET или Java на клиенте.

  3. Транспорт должен быть HTTP или HTTPS. То есть: он должен легко проходить через брандмауэры; нет RPC или DCOM.
  4. Он должен быть относительно надежным, с повторными попытками и т. Д. Обязательна защита от повторов.
  5. Должно быть масштабируемым - там много трафика. Влияние каждого сообщения на сервер должно быть минимальным.
  6. Серверная часть - C #, в настоящее время использующая ASP.NET для реализации простого механизма HTTP POST.
  7. (немного странный). Он должен поддерживать клиентские очереди в памяти, чтобы мы могли не раскручивать жесткий диск. Он должен периодически выполнять сброс на диск.
  8. Он должен подходить для использования в проприетарном продукте (т. Е. Без GPL и т. Д.).

Ответы [ 4 ]

3 голосов
/ 05 января 2010

Как ваше текущее решение показывает его возраст?

Я бы выдвинул логику на задний план и сделал бы клиентов максимально простыми.

  1. Сообщения просто сохраняются в файловой системе. Пусть клиент напишет в c: / queue / {uuid} .tmp. Когда файл будет записан, переименуйте его в c: / queue / {uuid} .msg. Это делает запись сообщений в очередь на клиенте «атомарной».

  2. Поток C ++ просыпается, сканирует c: \ queue для файлов "* .msg" и, если он находит один, проверяет сервер, и HTTP отправляет ему сообщение. Когда он получает статус 200 обратно от сервера (то есть получил сообщение), он может удалить файл. Сканирует только файлы * .msg. Файлы * .tmp все еще пишутся, и у вас может быть состояние гонки, которое пытается отправить файл msg, который все еще записывается. Вот для чего нужно переименовать из .tmp. Я также рекомендовал бы сканировать по дате создания, чтобы ранние сообщения были первыми.

  3. Ваш сервер получает сообщение, и здесь он может провести любую необходимую проверку. Перенесите эту нагрузку на сервер, чтобы централизовать его. Вы можете просто записать каждый uuid для каждого сообщения, чтобы устранить дублирование. Если этот список становится слишком длинным (я не знаю объем вашего трафика), возможно, вы можете отбросить его из элементов, превышающих 30 дней (я также не знаю, как долго ваши клиенты могут оставаться в автономном режиме).

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

Если ваши клиенты стабильны, это довольно низкий риск. С помощью двойной проверки, основанной на идентификаторе сообщения, вы можете уменьшить это за счет некоторой бухгалтерии, но ведение списка uuids не слишком впечатляет, но опять же это зависит от объема вашего сообщения и других требований к производительности.

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

1 голос
/ 05 января 2010

Честно говоря, перечисленные требования не имеют большого смысла и показывают, что вам предстоит долгий путь в изучении MQ. Учитывая, что, если вы не хотите использовать MSMQ (возможно, самый простой в Windows - но с [IMO суровыми] ограничениями), то вам следует рассмотреть:

qpid - Достойное использование стандарта AMQP

zeromq - (лучший, IMO, технически, но также требует наибольшего знакомства с технологиями MQ)

Я бы тоже порекомендовал rabbitmq, но это сервер Erlang, и в последний раз я смотрел, что у него нет удобных библиотек C или C ++. Тем не менее, если вы делаете покупки в MQ, взгляните на это ...

[EDIT]

Я вернулся и перечитал ваши требования, а также некоторые ваши комментарии и подумал, что, возможно, клиентский MQ -> сервер - не ваш лучший вариант. Я мог бы, возможно, рассмотреть вопрос о том, чтобы позволить вашему клиенту -> серверным операциям быть HTTP POST или SOAP и разрешить конечной точке HTTP по очереди помещать сообщения в очередь на ваш бэкэнд MQ. IOW, абстрагируйте клиента MQ в архитектуру, над которой у вас больше контроля. Тогда ваш клиент C ++ будет просто HTTP (простой), а ваша служба HTTP (вероятно, C # / .Net после чтения ваших комментариев) может взаимодействовать с любым MQ-сервером по вашему выбору. Если ваша конечная точка HTTP будет порождать MQ-сообщения, она будет чертовски легкой и сможет масштабировать все традиционные методы балансировки нагрузки.

0 голосов
/ 05 января 2010

Как насчет использования библиотеки асинхронных агентов из .NET Framework 4.0. Это все еще бета, хотя.

http://msdn.microsoft.com/en-us/library/dd492627(VS.100).aspx

0 голосов
/ 05 января 2010

В прошлый раз, когда я хотел сделать любой обмен сообщениями, я использовал C # и MSMQ. Существуют библиотеки MSMQ, которые делают использование MSMQ очень простым. Это бесплатно для установки на обоих серверах и никогда не терял сообщения по сей день. Он обрабатывает перезагрузки и т. Д. Сам по себе. Это прекрасная вещь, и ежедневно обрабатываются 100 000 сообщений.

Я не уверен, почему вы исключили MSMQ, а я не получил пункт 2.

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

...