2012-10-12 63 views
0

我想安裝使用NHibernate持久性NServiceBus Sagas,但我想我有東西配置不正確,因爲我得到一個錯誤連接到服務在127.0.0.1:8080 。我能夠處理命令消息,但幾秒鐘之後,控制檯窗口中會出現下面的錯誤消息,然後再次觸發相同的命令,導致事件中的處理程序再次被調用。只要我允許應用程序運行,就會重複發生這種情況。我可以告訴NHibernate連接到我的數據庫,因爲它爲傳奇數據創建了一個表,但是沒有任何東西永遠保留在該表中。NServiceBus使用NHibernate的Sagas - 無法連接到遠程服務器

我認爲有一個錯誤,堅持傳奇數據,我的猜測是它可能試圖使用默認的RavenDb傳奇持久性,但我不知道爲什麼會這樣。

我收到錯誤信息是:

WARN NServiceBus.Unicast.Transport.Transactional.TransactionalTransport [(空)] <(空)> - 無法提高 'transportmessage接收' 事件 對於ID = 3753b476-7501-4fd8-90d0-b10aee95a578 \ 22314 的消息System.Net.WebException:無法連接到遠程服務器---> System.Net.Sockets.SocketException:無法建立連接 因爲目標機器主動拒絕它127.0.0.1:8080在 Sy ssh.interface.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP)at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4,Socket S6中,插座&插座,ip地址&地址, ConnectSocketState狀態,IAsyncResult的asyncResult,異常& 除外)---內部異常堆棧跟蹤的末尾在 NServiceBus.Unicast.UnicastBus.HandleTransportMessage(IBuilder childBuilder,TransportMessage MSG )at NServiceBus.Unicast.UnicastBus.TransportMessageReceived(Object sender, Transpo rtMessageReceivedEventArgs e)上在 NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.OnTransportMessageReceived(TransportMessage MSG)

我傳奇的樣品 System.EventHandler`1.Invoke(對象發件人,TEventArgs E)嘗試使用的(沒有什麼花哨這裏,同樣的事情發生了,我是否真正做到在手柄方法的東西):

public class ItemSaga : Saga<ItemData>, IAmStartedByMessages<CreateItemCommand> 
{ 
    public void Handle(CreateItemCommand message) 
    { 

    } 
} 

public class ItemData : ISagaEntity 
{ 
    public Guid Id { get; set; } 
    public string Originator { get; set; } 
    public string OriginalMessageId { get; set; } 
} 

我的端點配置是這樣的:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization 
{ 


    public void Init() 
    { 

     var container = new UnityContainer(); 
     container.AddNewExtension<Domain.UnityExtension>(); 

     Configure.With() 
      .UnityBuilder(container) 
      .JsonSerializer() 
      .Log4Net() 
      .MsmqSubscriptionStorage() 
      .MsmqTransport() 
       .PurgeOnStartup(true) 
      .UnicastBus() 
       .ImpersonateSender(false) 
      .DisableTimeoutManager() 
      .NHibernateSagaPersister() 
      .CreateBus() 
      .Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install()); 
    } 
} 

而且我的app.config如下:

<MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/> 
    <MsmqTransportConfig NumberOfWorkerThreads="1" MaxRetries="5"/> 

    <NHibernateSagaPersisterConfig UpdateSchema="true"> 
    <NHibernateProperties> 
     <add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider"/> 
     <add Key="connection.driver_class" Value="NHibernate.Driver.Sql2008ClientDriver"/> 
     <add Key="connection.connection_string" Value="Data Source=(localdb)\v11.0;Integrated Security=True;AttachDbFileName=|DataDirectory|\App_Data\EventStore.mdf"/> 
     <add Key="dialect" Value="NHibernate.Dialect.MsSql2012Dialect"/> 
    </NHibernateProperties> 
    </NHibernateSagaPersisterConfig> 

    <connectionStrings> 
    <add name="EventStore" connectionString="Data Source=(localdb)\v11.0;Integrated Security=True;AttachDbFileName=|DataDirectory|\App_Data\EventStore.mdf" 
     providerName="System.Data.SqlClient" /> 
    </connectionStrings> 

    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <dependentAssembly> 
     <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" /> 
     <bindingRedirect oldVersion="0.0.0.0-3.3.0.4000" newVersion="3.3.1.4000" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 

只是一對夫婦的注意事項:

這是我使用來測試此功能的示例應用程序。它使用本地數據庫文件附加到localdb,但是我使用SQL Server 2012的完整應用程序表現出相同的行爲。我還必須爲NHibernate添加一個dependenteAssembly條目,因爲NServiceBus.NHibernate NuGet包當前綁定到較舊的程序集版本(截至此發佈)。你可以看到,我也使用Unity作爲我的IOC,但是我也使用Ninject來複制這個項目。我正在使用EventStore來管理我的域名存儲,這非常棒。我有命令處理程序處理命令並通過EventStore發佈事件以供其他進程處理。然而,我試過禁用所有那些只有我的佐賀作爲命令處理程序離開我,我仍然得到相同的錯誤。

有沒有人有任何想法,我可能做錯了什麼?

+0

似乎端點仍然連接到RavenDB。你可以嘗試https://github.com/NServiceBus/NServiceBus/blob/master/src/timeout/NServiceBus.Timeout.Hosting.Windows/Config/ConfigureTimeoutManager.cs#L27在內存中運行timeoutmanager,以排除bug在TimeoutManager配置? –

+0

你也應該刪除.CreateBus()。開始(...),因爲主機會爲你做這個 –

+0

感謝Andreas的建議。但是,即使在內存超時管理器中,我仍然遇到同樣的錯誤。 – Jeremy

回答

0

我找到了解決我的問題的方法。這似乎是使用內置NServiceBus配置文件的問題。我沒有在主機的命令行參數中指定配置文件,因此默認情況下它正在加載NServiceBus.Production配置文件。默認情況下,Production配置文件使用RavenDB提供所有持久性。

望着在GitHub上NServiceBus源,生產檔案處理程序包含在ProfileActivated方法如下:

Configure.Instance.RavenPersistence(); 

if (!Configure.Instance.Configurer.HasComponent<ISagaPersister>()) 
    Configure.Instance.RavenSagaPersister(); 

if (!Configure.Instance.Configurer.HasComponent<IManageMessageFailures>()) 
    Configure.Instance.MessageForwardingInCaseOfFault(); 

if (Config is AsA_Publisher && !Configure.Instance.Configurer.HasComponent<ISubscriptionStorage>()) 
    Configure.Instance.RavenSubscriptionStorage(); 

幾件事情要注意這裏:

  • 輪廓總是會調用RavenPersistence() 配置實例。我還沒有深入探討 方法的內部工作方式,以確定如果其他 持久性已被定義,它是否會實際繞過配置Raven,但它將始終運行此方法。
  • 當我附加到NServiceBus源代碼並通過 調試此代碼時,在第二行HasComponent中返回 false導致RavenSagaPersister配置運行。即使我已經在端點 配置中定義了NHibernateSagaPerister,這個 也會發生。

我不確定這種行爲是否由我設計,錯誤或配置錯誤。不過,我的解決方法是創建我自己的配置文件。我必須將NHibernate配置調用從我的端點配置移動到我的新配置文件,但是一旦我這樣做了,我就可以使用NHibernate持久性而不會出錯。

我的自定義配置文件如下所示(我借了從生產型材的日誌處理程序日誌處理程序):

public class MyProfile : IProfile 
{ 

} 

internal class MyProfileProfileHandler : IHandleProfile<MyProfile>, IWantTheEndpointConfig 
{ 
    void IHandleProfile.ProfileActivated() 
    { 
     Configure.Instance.NHibernateUnitOfWork(); 
     Configure.Instance.NHibernateSagaPersister(); 
     Configure.Instance.DBSubcriptionStorage(); 
     Configure.Instance.UseNHibernateTimeoutPersister(); 
    } 

    public IConfigureThisEndpoint Config { get; set; } 
} 

public class MyProfileLoggingHandler : IConfigureLoggingForProfile<MyProfile> 
{ 
    void IConfigureLogging.Configure(IConfigureThisEndpoint specifier) 
    { 
     SetLoggingLibrary.Log4Net<RollingFileAppender>(null, 
      a => 
      { 
       a.CountDirection = 1; 
       a.DatePattern = "yyyy-MM-dd"; 
       a.RollingStyle = RollingFileAppender.RollingMode.Composite; 
       a.MaxFileSize = 1024 * 1024; 
       a.MaxSizeRollBackups = 10; 
       a.LockingModel = new FileAppender.MinimalLock(); 
       a.StaticLogFileName = true; 
       a.File = "logfile"; 
       a.AppendToFile = true; 
      }); 

     if (GetStdHandle(STD_OUTPUT_HANDLE) == IntPtr.Zero) 
      return; 

     SetLoggingLibrary.Log4Net<ColoredConsoleAppender>(null, 
      a => 
      { 
       LiteLoggingHandler.PrepareColors(a); 
       a.Threshold = Level.Info; 
      } 
    ); 
    } 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern IntPtr GetStdHandle(int nStdHandle); 
    const int STD_OUTPUT_HANDLE = -11; 
} 

最後一點,我也不得不將所有我的傳奇數據對象的屬性作爲虛擬的,按照標準的NHibernate實踐。一旦系統實際使用NHibernate,這變得非常明顯。

public class ItemData : ISagaEntity 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string Originator { get; set; } 
    public virtual string OriginalMessageId { get; set; } 
} 

這是一個很長的解釋,但希望它能幫助其他人在路上。如果任何人有更好的方法來實現這一點,或正確的方式來使用配置文件,請讓我知道!

相關問題