NServiceBus: совместное использование библиотек DLL сообщений

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

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

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

Останутся ли все остальные девять подписчиков в силе? Будут ли они работать как обычно со старой библиотекой Message DLL, или все они должны быть обновлены новой библиотекой DLL, перекомпилированы и выпущены?


person Paul T Davies    schedule 04.08.2011    source источник


Ответы (2)


Архитектура NServiceBus спроектирована так, чтобы быть устойчивой к изменениям структуры сообщений (особенно если изменения включают добавление информации, как в вашем сценарии). См. страницу пример управления версиями на сайте NServiceBus.

person Eric Farr    schedule 04.08.2011
comment
Это не тот случай. Смотрите мой ответ ниже. - person tom redfern; 04.08.2011
comment
Он отлично работает — просто не увеличивайте атрибут AssemblyVersion — вместо этого используйте AssemblyFileVersion. Смотрите мой комментарий к ответу @hugh. - person David Boike; 05.08.2011
comment
Обновление - наконец-то получилось попробовать: я оставил атрибут AssemblyVersion нетронутым, и он отлично работает! - person Paul T Davies; 08.08.2011
comment
Я рад, что у вас это работает, однако это, так сказать, заделка трещин. Первоначальная проблема, с которой вы столкнулись, не исчезла, вы просто решаете ее, не разрешая управление версиями в своей сборке обмена сообщениями. - person tom redfern; 20.08.2011
comment
Я согласен с @hugh. Отсутствие изменения AssemblyVersion — проблема, ожидающая своего решения. Действительно, я видел это в действии, когда два компонента в одной и той же системе совместно использовали dll контракта, где только один был обновлен, но этот номер версии остался прежним. Из-за настроек установки, использующих эту версию для отслеживания того, кто использует одни и те же DLL на машине, установка не удалась, когда Windows поняла, что они не совпадают. - person gouldos; 06.02.2013

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

Это можно сделать, если вы реализуете NSB в сценарии отправки/получения. В этом случае, несмотря на то, что контракт является DLL-библиотекой сообщений, отправителям и получателям не обязательно использовать одну и ту же версию DLL. Это связано с тем, что предоставление XML по сети приведет к чистой десериализации на стороне получателя, и все будет хорошо.

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

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

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

Вы должны знать об этой жесткой зависимости в сценарии pub-sub.

Надеюсь это поможет.

Изменить

Начиная с версии 3.x NServiceBus, если основная версия сборки сообщений совместно используется издателем и подписчиком, публикация-подписка будет работать как обычно.

person tom redfern    schedule 04.08.2011
comment
Я не сталкивался с этой проблемой раньше. Можно ли этого избежать, имея общий высокоуровневый интерфейс, который реализуют все сообщения определенного типа (и не будут изменяться) и подписываются на него? - person Eric Farr; 04.08.2011
comment
Я не пробовал это (интерфейс в виде сообщений), но теоретически это может сработать. Как вы сказали, вы можете развивать фактические сообщения отдельно для издателя/подписчика. Однако на практике я не знаю, поэтому вам придется попробовать. - person tom redfern; 04.08.2011
comment
То, чем вы пытаетесь поделиться между службами, — это схема сообщения, так получилось, что она представлена ​​сборкой, потому что это структура, которую нам предоставляет Microsoft. Решение в этом случае состоит в том, чтобы не реализовывать атрибут AssemblyVersion и всегда оставлять его равным 1.0. Если вам необходимо отслеживать версии, увеличьте значение атрибута AssemblyFileVersion. Вы можете сделать это, не нарушая механизм публикации/подписки. - person David Boike; 05.08.2011
comment
Я согласен, что если вы оставите сборочные версии в покое, у вас не будет никаких проблем. Однако, если вы работаете в среде CI, часто маркировка/управление версиями автоматически увеличивается для каждой сборки. - person tom redfern; 06.08.2011
comment
Было бы лучше не полагаться на получение правильной dll с правильной версией и разрешить десериализацию этого сообщения в любой класс, поскольку все, что действительно имеет значение, - это схема, а не информация о типе. - person rpgmaker; 10.08.2011
comment
Чтобы не засорять этот поток, я сделал это со своей реализацией ESB. PServiceBus (pservicebus.codeplex.com) - person rpgmaker; 10.08.2011
comment
As of version 3.x of NServiceBus as long as your messages assembly major version is shared between publisher and subscriber then pub-sub will work as normal. -- Пробовал в v6, и даже изменения номера ревизии было достаточно, чтобы сломать его. - person Sinaesthetic; 30.11.2016