无法让NServiceBus不抛出异常(MessageQueueException,SqlException,TimeoutPersisterReceiver)

时间:2017-09-18 10:07:54

标签: c# .net nservicebus nservicebus5

我有一个非常令人沮丧的NServiceBus问题,我似乎无法弄清楚。我希望你们能够对这种情况有所了解。

我目前正在使用NServiceBus.Core v5.0和NServiceBus.Host v6.0并以不显眼模式运行它。

似乎无论我使用什么配置,我总会遇到某种错误。我将从产生最少问题的配置开始:

案例1 - 使用自定义程序集扫描:

public void Customize(BusConfiguration configuration)
    {
        var endpointName = typeof(EndpointConfig).Namespace;
        configuration.SetUniqueHostId(endpointName);

        configuration.UseSerialization<JsonSerializer>();
        configuration.UsePersistence<NHibernatePersistence, StorageType.Outbox>();

        configuration.AssembliesToScan(new List<Assembly>
        {
            GetType().Assembly,
            typeof(ICustomCommand).Assembly
        });

        configuration.Conventions()
            .DefiningCommandsAs(type => typeof(ICustomCommand).IsAssignableFrom(type));

        configuration.EnableDurableMessages();
        configuration.EnableInstallers();

        var container = ContainerInitializer.Container;
        configuration.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(container));
    }

我在这里注意到的问题如下:

  1. 启动NServiceBus主机应用程序并且持久性SQL数据库尚不存在时,不会抛出异常,说无法找到数据库(在案例2中也是如此)。

  2. 我一直收到以下异常:

  3.   

    NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver无法从超时存储中获取超时

    最终会导致应用程序崩溃,因为当此错误发生的次数太多时,ServiceBus会判断出足够多并且只会引发致命异常。

    1. 除了上述问题之外,应用程序还可以完美地接收和处理消息......直到发生致命异常
    2. 现在,这个有点困难:

      案例2 - 使用默认程序集扫描:

      public void Customize(BusConfiguration configuration)
          {
              var endpointName = typeof(EndpointConfig).Namespace;
              configuration.SetUniqueHostId(endpointName);
      
              configuration.UseSerialization<JsonSerializer>();
              configuration.UsePersistence<NHibernatePersistence, StorageType.Outbox>();
      
              // !! DISABLED !!
              // configuration.AssembliesToScan(new List<Assembly>
              // {
              //    GetType().Assembly,
              //    typeof(ICustomCommand).Assembly
              // });
      
              configuration.Conventions()
                  .DefiningCommandsAs(type => typeof(ICustomCommand).IsAssignableFrom(type));
      
              configuration.EnableDurableMessages();
              configuration.EnableInstallers();
      
              var container = ContainerInitializer.Container;
              configuration.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(container));
          }
      

      在这种情况下会出现以下问题:

      当持久性SQL数据库尚不存在时:

      1. 启动NServiceBus主机应用程序并且SQL数据库不存在时,抛出异常 - 预期行为(这是正面的)
      2. 创建持久性SQL数据库后:

        1.   

          ServiceControl.Plugin.Nsb5.Heartbeat.Heartbeats |无法将心跳发送到ServiceControl:   NServiceBus.Unicast.Queuing.QueueNotFoundException:无法向地址发送消息:[Particular.ServiceControl@MYPCNAME]

        2.   

          抛出异常:&#39; System.Messaging.MessageQueueException&#39;在System.Messaging.dll中   附加信息:外部组件抛出了异常。

        3.   

          2017-09-15 16:25:45.6743 | Warn | NServiceBus.Unicast.Messages.MessageMetadataRegistry | Message header&#39; SharedTemp.Interfaces.ICustomCommand&#39;   被映射到类型&#39; SharedTemp.Interfaces.ICustomCommand&#39;但在消息注册表[...]

          中找不到该类型
        4.   

          抛出异常:&#39; System.Exception&#39;在NServiceBus.Core.dll中   其他信息:无法找到“Newtonsoft.Json.Linq.JObject&#39;”的元数据。

        5. 现在,自NServiceBus文档声明以来,异常3和4特别(没有双关语意)奇怪:

            

          默认情况下,扫描端点bin目录中的所有程序集以查找实现其接口的类型,以便它可以自动配置它们。

          &#34; Newtonsoft.Json&#34;和我的#34; SharedTemp dll&#34; s&#34;确实在BIN文件夹中,但NServiceBus似乎没有找到它们。至于第1点:NServiceBus不为我创建该队列,但它创建了我需要的所有其他队列。

          最后总是请求的app.config文件:

              <?xml version="1.0" encoding="utf-8"?>
          <configuration>
            <configSections>
              <section name="MasterNodeConfig" type="NServiceBus.Config.MasterNodeConfig, NServiceBus.Core"/>
              <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core"/>
              <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core"/>
              <section name="AuditConfig" type="NServiceBus.Config.AuditConfig, NServiceBus.Core"/>
            </configSections>
            <appSettings>
              <add key="NServiceBus/Persistence/NHibernate/dialect" value="NHibernate.Dialect.MsSql2012Dialect"/>
              <add key="NServiceBus/Outbox" value="true"/>
            </appSettings>
            <MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/>
            <UnicastBusConfig>
              <MessageEndpointMappings />
            </UnicastBusConfig>
            <AuditConfig QueueName="audit"/>
            <connectionStrings>
              <add name="NServiceBus/Persistence" connectionString="Server=(LocalDB)\v11.0;Initial Catalog=NServiceBus;Integrated Security=true"/>
            </connectionStrings>
            <system.web>
              <membership defaultProvider="ClientAuthenticationMembershipProvider">
                <providers>
                  <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri=""/>
                </providers>
              </membership>
              <roleManager defaultProvider="ClientRoleProvider" enabled="true">
                <providers>
                  <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400"/>
                </providers>
              </roleManager>
            </system.web>
            <startup>
              <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
            </startup>
            <MasterNodeConfig Node="localhost"/>
          </configuration>
          

          有没有人对此有任何想法?

1 个答案:

答案 0 :(得分:0)

经过大量的搜索,我终于找到了问题!

首先,我使用了一个内部NuGet包,它可以帮助我配置NServiceBus。该软件包适用于其他项目,但对于我的不太好,因为我使用的是JsonSerialization而不是默认的XML序列化。

该软件包的第一个问题是它使用了&#34; INeedInitialization&#34;用于配置NServiceBus的接口。在我的代码中,我将调用&#34; IConfigureThisEndpoint&#34;启用JsonSerialization。这里的问题是,当启动NServiceBus主机时,它将无法找到NewtonSoft.Json库。如果我随后将自定义程序集扫描添加到我自己的配置代码中,则不会触发&#34; INeedInitialization&#34;,导致配置不完整/不正确。

我认为它无法加载NewtonSoft.Json库,因为扫描是在包的代码/命名空间中触发的?也许@Sean Farmer可以回答这个问题?

该软件包的第二个问题是它会向app.config添加连接字符串,一个用于&#34; NServiceBus / Persistence&#34;和#34; NServiceBus / Persistence / NHibernate / Saga&#34;。我没有使用Saga,因此不需要连接字符串。最初这不是问题,因为我第一次抓到它,但在重新安装包后我完全忘了它。再次删除它似乎也使NServiceBus更快乐。

那么,最终起作用了什么?我删除了包并自行完成配置,结果如下:

public void Customize(BusConfiguration configuration)
    {
        var endpointName = typeof(EndpointConfig).Namespace;
        configuration.UniquelyIdentifyRunningInstance().UsingCustomIdentifier(endpointName);

        configuration.EnableOutbox();
        configuration.UsePersistence<NHibernatePersistence>();
        configuration.Transactions().DefaultTimeout(TimeSpan.FromMinutes(5.0));

        configuration.UseSerialization<JsonSerializer>();

        configuration.Conventions()
            .DefiningCommandsAs(type => typeof(ICustomCommand).IsAssignableFrom(type));

        configuration.EnableDurableMessages();
        configuration.EnableInstallers();

        var container = ContainerInitializer.Container;
        configuration.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(container));
    }

@Sean:谢谢你允许我与你联系。幸运的是没有必要

@Mike:感谢您输入