0

私たちは現在、マルチテナントの側面を処理する方法に関連して、いくつかのランダムな奇妙な動作を実行しているマルチテナント アプリケーションに取り組んでいます。

背景: 複数のエンド ユーザー グループが使用する ASP.NET アプリケーションがあります。アプリケーションへのアクセスに使用する URL によって、関連付けられている会社が決まり、最終的にデータベース接続文字列が決まります。特定の Company ID をホスト名にマップする CompanyHost マッピングの静的リストを保存します。静的リストに一致するものが見つからない場合は、データベースからリストを再度取得します。

アプリケーションが最初に起動すると、接続が正しくプルアップされ、ホストの正しい会社 ID が検出されます。ただし、未知の期間が経過すると、アプリケーションはすべてのホスト ヘッダーに対して空の ID を返し始めます。それらがデータベース内に存在する場合でも、アプリケーションは接続文字列を特定できなくなります。サーバーにアクセスしてアプリケーション プールをリサイクルすると、問題が解決します。アプリケーション プールのリサイクル時間を短く (2 時間) 設定して回避しようとしましたが、十分に短くないか、問題ではありません。

以下は、ホストによって企業 ID を取得するスニペットです。これは、有効なホスト名に対しても空の Guid を返しています。

private static List<CompanyHost> lCompanyHosts = new List<CompanyHost>();

public static string Host
{
    get { return HttpContext.Current.Request.Url.DnsSafeHost; }
}

public static Guid CompanyIDByHost
{
    get
    {
        Guid gCompany_ID = Guid.Empty;

        lock (lCompanyHosts)
        {
            if (lCompanyHosts.Count == 0)
                lCompanyHosts = new CompanyHostDataLogic().RetrieveAll();

            gCompany_ID = lCompanyHosts.Where(ch => ch.hostname.ToLower() == Host.ToLower()).Select(ch => ch.company_id).FirstOrDefault();

            if (gCompany_ID == Guid.Empty)
            {
                lCompanyHosts = new CompanyHostDataLogic().RetrieveAll();
                gCompany_ID = lCompanyHosts.Where(ch => ch.hostname.ToLower() == Host.ToLower()).Select(ch => ch.company_id).FirstOrDefault();
            }
        }

        return gCompany_ID;
    }
}

正常に動作している期間が経過した後、有効なホストに対して Guid Empty が返される理由を理解するのに苦労しています。私の最善の推測では、問題の原因となっている Web サイトでの非アクティブ期間に関係があると思われます。ただし、これを解決する最善の方法がわかりません。

不足しているものはありますか、またはこのタイプの機能を実装するためのより良い方法はありますか?

4

2 に答える 2

0

問題であり、ここでの私の解決策に対する最終的な答えは、このプロセスがアプリケーションプールの起動時に発生していたことです。実際のリクエストが発生する前は、キーとして使用されていたホスト名はnullでした。

これにより、私たちが見ていたエラーが奇妙な動作を引き起こしました。

初期ロードを静的オブジェクトに変更し、動的ロードを遅延ロードとして追加した後、問題は解決しました。

于 2012-09-20T20:25:05.893 に答える
0

これはコメントとして始まりましたが、コードの書式設定の恩恵を受けると思います。完全な答えではありませんが、次のアプローチでより良い結果が得られる可能性があります。

RetrieveAll()問題を飲み込むことができますか?新しいホスト名が入ってくると、リスト全体をリセットしますがlCompanyHosts、それが失敗するとすべてが失われます。おそらくCompanyHostDataLogic、単一の「CompanyHost」を取得するメソッドを追加してから、それをあなたのList<CompanyHost> lCompanyHosts

        if (lCompanyHosts.Count == 0)
            lCompanyHosts = new CompanyHostDataLogic().RetrieveAll();

        gCompany_ID = lCompanyHosts.Where
                        (ch => ch.hostname.ToLower() == Host.ToLower())
                        .Select(ch => ch.company_id).FirstOrDefault();

        if (gCompany_ID == Guid.Empty)
        {
            CompanyHost newEntry = 
                          new CompanyHostDataLogic().RetrieveOne(string Host);
            if(newEntry!=null)
                lCompanyHosts.Add(newEntry);

            gCompany_ID = lCompanyHosts.Where
                           (ch => ch.hostname.ToLower() == Host.ToLower())
                           .Select(ch => ch.company_id).FirstOrDefault();

        }

変更を加えることができない場合は、代わりに の結果を既存のリストとCompanyHostDataLogicマージできます。RetrieveAll()原則は同じです。既存のリストをリセットせず、新しい値または更新された値をリストに追加するだけです。

于 2012-05-09T19:05:35.027 に答える