2016-09-22 3 views
0

問題:このサービスが開始されたときにDBがオフラインの場合、このサービスはこの行の中で失敗するため開始しません。開始時にはvar container = new BootStrapper().Container;です。dbがcastle windsorとnhibernate facilityを使用してオフラインになっている場合、Windowsサービスの起動を再試行する方法はありますか?

private static void Main(string[] args) 
{ 
    Logger.Info("Engine Service is bootstrapping..."); 
    AppDomain.CurrentDomain.UnhandledException += UncaughtExceptions.DomainException; 
    Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); 

    var container = new BootStrapper().Container; 
    var controller = container.Resolve<EngineController>(); 
    ServiceBase.Run(controller.MainView as ServiceBase); 

    container.Dispose(); 
} 

それはそれはそれはNHibernateは施設container.AddFacility<NHibernateFacility>();を追加し、接続タイムアウトで失敗し、このコードを実行されることがある失敗した理由。

public void Install(IWindsorContainer container, IConfigurationStore store) 
{ 
    var isAutoTxFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is AutoTxFacility); 
    if (!isAutoTxFacilityRegistered) container.AddFacility<AutoTxFacility>(); 

    container.Register(
     Component.For<INHibernateInstaller>().ImplementedBy<CieFluentInstaller>().IsDefault().LifestyleTransient(), 
     Classes.FromThisAssembly().Pick().WithService.DefaultInterfaces().LifestyleTransient() 
     ); 

    var isNHibernateFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is NHibernateFacility); 
    if (!isNHibernateFacilityRegistered) container.AddFacility<NHibernateFacility>(); 
} 

Windowsサービスが起動している場合は、アプリケーションサービスの開始に失敗した(それは更新やバックアップがDB上で行われている可能性がある場合)30秒よりも長くかかります。

私はFluentNhibernate、NHibernate、NHibernateFacilityのCastle Windsorを使用しています。私が試した

物事:それ はビューまたはコントローラに到達する前に、それが失敗したので

  • は、サービス開始イベントからそれを行うことはできません。ビューとコントローラには、IoCコンテナに直接アクセスする がありません。城ウィンザーの推奨に従って注入されたIoCFactory を介してのみです。

  • 私は再試行ループをメインにスレッドを生成し、 であり、それを始めることを試みましたが、 ServiceBase.Runメソッド内サービス「待機」ので、私は正しいのように見えることはできません再試行ループ中に に戻って "偽の開始"にします。

  • は、サービス開始のタイムアウトを長く研究し、それはその前に失敗し、生産現場の何百ものシステム全体の 変更はオプションではありませんので、 servicebase /ビューにアクセスすることはできません。

質問:設計上、DBがオフラインのときにWindowsサービスが "開始"するようにするにはどうすればよいですか?

答えて

0

NHibernateのバグで、上記を実行できなくなったことが判明しました。 Nibernate 2.0と3.0の間にあなたがNHibernateのv3.0の+設定(またはこの場合FluentNHibernate中)に以下を追加する必要があります。

cfg.SetProperty("hbm2ddl.keywords", "none"); 

これは、NHibernateのが適切自体をブートストラップし、エラーなしで今コントローラに取得することができます。

1

次の2つのカテゴリにあなたの起動アクションを分割する必要があります。かなりすぐに起こる必要があり、および/または障害が発生した場合に自分自身を 修正されません

  1. アクション。必須の構成ファイル などが欠落しています。管理者の介入が必要となります。

  2. 私たちは遅らせることができますか、より重要なのは、 のアクションは、一時的なエラーのために失敗します。このようなエラーはネットワーク障害であるか、 再起動後にデータベースサーバーよりも少し早く起動する可能性があります。

あなたのサービスOnStartコードは、この基本構造に従ってください:

ManualResetEvent shutdownRequestedEvent = new ManualResetEvent() 

RealMain: 
    while (!shutdownRequestedEvent.WaitOne(0) && !bootstrapPerformed) 
    { 
     try 
     { 
      PerformBootstrap() 
      bootstrapPerformed = true 
     } 
     catch (Exception ex) 
     { 
      LogError(ex) 
     } 

     if (!bootstrapPerformed) 
      shutdownRequestedEvent.WaitOne(some timeout) 
    } 

    Second bootstrap action similar to above, etc. 

    Third bootstrap action similar to above, etc. 

    Eventually, start performing real work, while listening to 
    the shutdownRequestedEvent. 

サービス: "メインアプリケーションスレッド" へ

OnStart: 
    Perform the immediate category 1 tasks and exit if any of these fail. 
    Launch the main application thread. 

一つのアプローチは、この基本 構造に従うことですOnShutdownはshutdownRequestedEventを通知し、次に はRealMainスレッドが終了するのを待ちます。

RealMainスレッドがセットアップ以外の目的で使用されていない場合は、すべてのブートストラップタスクが完了したら、 を終了させる必要があります。

注意すべき点は、通常の操作でサービスが一時的なエラーのために一時的にリソースへのアクセスを失うのを防ぐことです。たとえば、誰かがデータベースサーバーを再起動しただけで、サービスがクラッシュすることはありません。それは辛抱強く待って永遠にやり直すべきです。

実際のタスクが何であっても、ブートストラップを依存関係として扱うこともできます。たとえば、実際のタスクを起動し、実際のタスクがデータベースセッションを要求し、セッションファクトリを持っていなければならないことを取得します。セッションファクトリをまだ持っていなければ、セッションファクトリの初期化を開始します。セッションファクトリ を作成できない場合、例外が発生し、タスク全体が失敗します。残りの 作業が少し待ってから、タスクを再試行するようになりました。永遠に繰り返す。

+0

最初に "none"に設定する必要がある "hbm2ddl.keywords"を必要とするNHibernateの問題のため、これは私の2番目の箇条書きの点よりもうまくいっていませんでした。 –

+0

はい、私の構造にはより広いアプリケーションがあります。たとえば、サービスが作業を開始する前にデータベースから情報を読み取ったり、クライアント要求のリスンを開始したりする必要がある場合があります。 –

関連する問題