当前位置: 首页 > 知识库问答 >
问题:

无法使NServiceBus不引发异常(MessageQueueException、SqlException、TimeoutPersisterReceiver)

卜飞鸣
2023-03-14

我有一个非常令人沮丧的NServiceBus问题,我似乎无法解决。我希望你们能对局势有所了解。

我目前正在使用NServiceBus。核心版本5。0和N服务总线。主机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));
    }

我注意到的问题如下:

>

  • 当启动NServiceBus主机应用程序并且数据库暂留SQL还不存在时,不会抛出异常说找不到数据库(在情况2中是这样)。

    我一直得到以下例外:

    NServiceBus.超时。主机。窗户。从超时存储中获取超时失败

    这最终导致应用程序崩溃,因为当这个错误发生太多次时,ServiceBus决定适可而止,并抛出一个致命的异常。

    现在,这个有点难:

    案例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数据库不存在时,会出现异常抛出-预期行为(这是肯定的)

    创建持久性SQL数据库后:

    >

    引发异常:“系统。信息。系统中的MessageQueueException。信息。dll附加信息:外部组件引发了异常。

    2017-09-15 16:25:45.6743警告服务巴士。单播。信息。MessageMetadataRegistry |消息头'SharedTemp。接口。ICUSTOMCOMAND“”已映射到类型“SharedTemp”。接口。ICUSTOMCOMAND',但在消息注册表中找不到该类型[…]

    引发异常:“系统。NServiceBus中的“异常”。果心dll其他信息:找不到“Newtonsoft”的元数据。Json。林克。JObject’。

    现在,例外情况3和4特别奇怪(并非双关语),因为NServiceBus文档说明:

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

    和“牛顿软”。Json"和我的"SharedTemp dll's"确实在BIN文件夹中,但是NServiceBus似乎没有找到它们。至于第1点:NServiceBus不会为我创建那个队列,但它会创建我需要的所有其他队列。

    最后是始终请求的应用程序。配置文件:

        <?html" target="_blank">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个答案

    壤驷安和
    2023-03-14

    经过多次搜索,我终于找到了问题!

    首先,我使用了一个内部NuGet包,该包应该可以帮助我配置NServiceBus。这个包在其他项目中运行良好,但在我的项目中运行不太好,因为我使用的是JsonSerialization,而不是默认的XML序列化。

    这个包的第一个问题是它使用了“INeed初始化”接口来配置NServiceBus。然后,在我的代码中,我将调用“IConfigreThisEndpoint”来启用JsonSeriize。这里的问题是,当启动NServiceBus主机时,它将无法找到NewtonSoft。Json图书馆。如果我随后将自定义程序集扫描添加到我自己的配置代码中,它将不会触发“INeed初始化”,从而导致不完整/不正确的配置。

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

    该软件包的第二个问题是,它会向应用程序添加连接字符串。配置,一个用于“NServiceBus/Persistence”,另一个用于“NServiceBus/Persistence/NHibernate/Saga”。我没有使用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));
        }
    

    @肖恩:谢谢你让我联系你。幸运的是没必要

    @迈克:谢谢你的意见

     类似资料:
    • 当方法运行时,我希望抛出一个异常(在测试时)。我能做的事情很少: 存根(mock.someMethod(“某些参数”)).ToThrow(new RuntimeException()); 当(mock.someMethod(“某些参数”)).thenThrow(new RuntimeException()) 放弃..... 通常我会创建一个spy对象来调用spied方法。使用stubbing我可以

    • 单元测试以空指针异常退出。SafeFile rootRepoDir的值为null,我不知道为什么。我嘲笑过它,那为什么它显示为null?如果我删除这一行,powerMockito.whennew(Safefile.class).withanyArguments().thenreturn(file1);则rootRepoDir的值为非空 我在PrepareForTest中添加了sc.class,使用

    • 我正在使用JAXB XMLadapter封送和反封送布尔值。应用程序的XML文件也将被C#应用程序访问。我们必须验证这个XML文件,这是使用XSD完成的。C#应用程序为布尔节点编写“true”值。但XSD也验证了这一点,因为它只允许“true/false”或“1/0”。因此,我们在XSD中保留了布尔值的String,该String将由XMLAdapter验证,以便在我们这边进行封送和反封送。XML

    • 你可以使用raise语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接导出类。 如何引发异常 例13.2 如何引发异常 #!/usr/bin/python # Filename: raising.py classShortInputException(Exception):     '''A u

    • 问题内容: 我正在使用JAXB XMLadapter来编组和解组布尔值。C#应用程序也将访问该应用程序的XML文件。我们必须验证此XML文件,这是使用XSD完成的。C#应用程序为布尔节点写入“ True”值。但是我们的XSD确实验证了同样的结果,因为它只允许“ true / false”或“ 1/0”。因此,我们在XSD中将String保留为布尔值,并且XMLAdapter会验证该字符串是否在我们

    • 问题内容: 这是我的代码块。 这段代码无法编译,因为我在Line1中添加了“ throws”。 编译器抱怨重写的方法不能引发异常。 为什么这样 ?。 为什么覆盖的方法不能引发异常? 因为我可以通过在子类的实现中添加n行代码来覆盖基类中的方法。 这些添加的代码会引发异常,所以为什么我不能在重写的方法中使用“引发”? 问题答案: 重写的方法可以引发Exception,只要被重写的方法也抛出相同的Exc