NServiceBus 序列化问题 - 似乎不支持序列化器配置

NServiceBus serialization problems - doesn't seem to honoring serializer configuration

所以我开始遇到 NServiceBus 的这个问题,它显然会接受消息并序列化它们,但似乎无法反序列化它们进行处理。我已经尝试通过几种不同的方式在设置中设置序列化程序。这是我从错误 queue.

中提取的一些异常(堆栈顶部)

// not setting the serializer. Appears that NServiceBus serializes as XML (as documented) but tries to deserialize using NewtonSoft

"NServiceBus.ExceptionInfo.StackTrace" : "NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from transport message 7cc546df-09ca-493e-bb6d-a6ce00a6bb10 ---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.\u000d\u000a at Newtonsoft.Json.JsonTextReader.ParseValue() in C:\Build\src\NServiceBus.Core\CircuitBreakers\CircuitBreaker.cs:line 0\u000d\u000a at NServiceBus.JsonMessageSerializer.Deserialize(Stream stream, IList`1 messageTypes) in C:\Build\src\NServiceBus.Core\Serializers\Json\JsonMessageSerializer.cs:line 108\u000d\u000a at ...


// with setting the serializer to the normal NServiceBus JsonSerializer (as in the tutorials). Looks like it can't deserialize JObject because it didn't include Newtonsoft in the scan. But why is it JObject at all?

"NServiceBus.ExceptionInfo.StackTrace" : "NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from transport message ee5c8703-f509-40aa-a187-a6ce00a7fd1e ---> System.Exception: Could not find metadata for 'Newtonsoft.Json.Linq.JObject'.\u000d\u000aEnsure the following:\u000d\u000a1. 'Newtonsoft.Json.Linq.JObject' is included in initial scanning. \u000d\u000a2. 'Newtonsoft.Json.Linq.JObject' implements either 'IMessage', 'IEvent' or 'ICommand' or alternatively, if you don't want to implement an interface, you can use 'Unobtrusive Mode'.\u000d\u000a at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageMetadata(Type messageType) in ...


// with setting the serializer to NewtonSoftSerializer it appears to be the same error "NServiceBus.ExceptionInfo.StackTrace" : "NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from transport message 603e07e7-7877-4d71-90b3-a6ce00a9370b ---> System.Exception: Could not find metadata for 'Newtonsoft.Json.Linq.JObject'.\u000d\u000aEnsure the following:\u000d\u000a1. 'Newtonsoft.Json.Linq.JObject' is included in initial scanning. \u000d\u000a2. 'Newtonsoft.Json.Linq.JObject' implements either 'IMessage', 'IEvent' or 'ICommand' or alternatively, if you don't want to implement an interface, you can use 'Unobtrusive Mode'.\u000d\u000a at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageMetadata(Type messageType) in ...

感觉 像其中一个或全部。根据我所看到的,我的想法是:

其他我认为有用的点:

任何见解都会有所帮助。为什么序列化器不排队?

这里有一些杂项:

配置:

public static void Initialize(
  string endpointName, 
  string instanceDescriminator, 
  IWindsorContainer container)
{
    _endpointConfiguration = new EndpointConfiguration(ServiceEndpoint.Surveys);
    _endpointConfiguration.SendFailedMessagesTo("error");
    _endpointConfiguration.MakeInstanceUniquelyAddressable(instanceDescriminator);
    _endpointConfiguration.UseContainer<WindsorBuilder>(customizations =>
    {
        customizations.ExistingContainer(container);
    });

    _endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Sagas>();
    _endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Subscriptions>();
    _endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Timeouts>();
    _endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.Outbox>();
    _endpointConfiguration.UsePersistence<NHibernatePersistence, StorageType.GatewayDeduplication>();
    _endpointConfiguration.EnableOutbox();
    _endpointConfiguration.UseTransport<SqlServerTransport>();
    _endpointConfiguration.EnableInstallers();

    NServiceBusConventions.SetDasConventions(_endpointConfiguration);
}

约定:

public static void SetDasConventions(EndpointConfiguration config)
{
    var conventions = config.Conventions();

    conventions.DefiningCommandsAs(type => type.Namespace != null && type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Command"));
    conventions.DefiningEventsAs(type => type.Namespace != null && type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Event"));
    conventions.DefiningMessagesAs(type => 
        type.Namespace != null && 
        (type.Namespace.StartsWith("DAS.Infrastructure.Messaging.Message") || type.Namespace.StartsWith("DAS.Infrastructure.Messaging")));
    conventions.DefiningEncryptedPropertiesAs(property => property.Name.StartsWith("Encrypted"));
    conventions.DefiningDataBusPropertiesAs(property => property.Name.EndsWith("DataBus"));
    conventions.DefiningExpressMessagesAs(type => type.Name.EndsWith("Express"));
    conventions.DefiningTimeToBeReceivedAs(type => type.Name.EndsWith("Expires") ? TimeSpan.FromSeconds(30) : TimeSpan.MaxValue);
}

事实证明,问题 似乎 是下游订阅者对存在问题的消息进行了较旧的修订。 objects 是相同的,但程序集修订版在我们的构建服务器上的每个构建上得到更新,然后推送到 Nuget(例如 1.0.0.45621)。据推测,只要主要修订版没有更改,NServiceBus 应该不会有问题,并且它仍然可以在指定的命名空间中找到名称为 object 的 object 。显然,这有一些细微差别,因为一旦我更新了另一个组件中的库,错误就停止了。

我从这个帖子中得到了灵感 https://groups.google.com/forum/#!topic/particularsoftware/lc7shFVR46k

Particular 的一位开发人员提到 NSB 需要避免在 headers 中使用 FQAN。我查看了错误中包含的消息中的 headers,我注意到 origin 是我正在处理的服务,并且显示了所附消息类型的 FQAN与该服务中使用的版本号不同的版本号。所以我打开了公交车上目前唯一的其他服务,发现有一个匹配。我更新了它,一切都很好。

我关注了那里提到的问题,但它看起来像是关闭了它以代替我不太明白的其他事情。无论如何,那是我的解决方案。我仍在寻求澄清,否则我将与他们开票,因为这在未来是不可持续的。开发人员将不断地在该共享库中工作,我们无法在每次进行更改时更新平台上每个微服务中的库(短时间内会超过 20 个)。