0

負荷分散サーバーに WCF サービス (Windows サービス上のホスト) を作成しました。このサービス インスタンスのそれぞれは、現在のユーザーのリストを維持します。たとえば、インスタンス A にはユーザー A001、A002、A005 があり、インスタンス B にはユーザー A003、A004、A008 などがあります。

各サービスには、ユーザー リストを取得するために使用するインターフェイスがあります。このメソッドは、すべてのサービス インスタンスのすべてのユーザーを返すことを期待しています。たとえば、インスタンス A またはインスタンス B からユーザー リストを取得すると、A001、A002、A003、A004、A005、および A008 が返されます。

現在、現在のユーザーのリストをデータベースに保存すると思いますが、このリストは頻繁に更新されるようです。

私の状況に合ったWCFサービス間でデータを共有する別の方法はありますか?

4

5 に答える 5

2

個人的には、データベース オプションは、現在のユーザーを保存するという概念に基づいているだけでは、やり過ぎのように思えます。実際にそれ以上を保存している場合は、データベースを使用するのが理にかなっています。しかし、単に WCF サービスの両方のインスタンスから現在のユーザーのリストが必要だと仮定すると、静的な汎用辞書のようなインメモリ ソリューションを使用します。サービスを一意に識別できる限り、一意のサービス ID をディクショナリのキーとして使用し、各キーをそのサービスのユーザー名 (または適切なユーザー データ構造) の一般的なリストとペアにするだけです。何かのようなもの:

private static Dictionary<Guid, List<string>> _currentUsers;

このディクショナリは 2 つの WCF サービス間で共有されるため、アクセスを同期する必要があります。これが例です。

public class MyWCFService : IMyWCFService
{
    private static Dictionary<Guid, List<string>> _currentUsers =
        new Dictionary<Guid, List<string>>();

    private void AddUser(Guid serviceID, string userName)
    {
        // Synchronize access to the collection via the SyncRoot property.
        lock (((ICollection)_currentUsers).SyncRoot)
        {
            // Check if the service's ID has already been added.
            if (!_currentUsers.ContainsKey(serviceID))
            {
                _currentUsers[serviceID] = new List<string>();
            }
            // Make sure to only store the user name once for each service.
            if (!_currentUsers[serviceID].Contains(userName))
            {
                _currentUsers[serviceID].Add(userName);
            }
        }
    }

    private void RemoveUser(Guid serviceID, string userName)
    {
        // Synchronize access to the collection via the SyncRoot property.
        lock (((ICollection)_currentUsers).SyncRoot)
        {
            // Check if the service's ID has already been added.
            if (_currentUsers.ContainsKey(serviceID))
            {
                // See if the user name exists.
                if (_currentUsers[serviceID].Contains(userName))
                {
                    _currentUsers[serviceID].Remove(userName);
                }
            }
        }
    }
}

特定のサービスに対してユーザーを 2 回リストしたくない場合は、 を に置き換えるのがおそらく理にかなってList<string>HashSet<string>ます。

于 2009-09-04T03:11:24.020 に答える
1

データベースは、アプリケーションにとって有用または重要な永続ストアを提供しているように見えます。さらに、それはあなたに役立つかもしれないトランザクションなどをサポートします。多くの更新はパフォーマンスの問題になる可能性がありますが、正確な数、クエリパターン、使用されるデータベースエンジン、地域などによって異なります。

このオプションの代わりに、memcachedのようなある種のインメモリキャッシングサーバーがあります。これはデータベースサーバーと同様の(一種の)方法で共有およびアクセスできますが、いくつかの注意点があります。まず、これらのプラットフォームは通常、ある種の永続ストレージに支えられていません。memcachedサーバーが停止するとどうなりますか?次に、ACIDに準拠していない可能性があります。追加と更新に関して、負荷がかかるとどうなりますか?

于 2009-09-04T02:12:57.880 に答える
1

私は記憶の方法が好きです。実際、私は現在取り組んでいるプロジェクトの 1 つと同じメカニズムを設計しています。これは、データベースにアクセスする機会がない場合や、マシン名に対するユーザーのリストなどの単純な情報を格納するためのテーブルを作成することに本当に消極的な人がいる場合に適しています。

私が行う唯一の更新は、ノードが利用可能なユーザーのリストをピアに返すだけで、ピアがそれを既存のリストと結合することです。次に、既存のリストを呼び出したピアに返します。それが、すべてのピアが同じリストと同期する方法です。

于 2011-08-11T03:34:12.840 に答える
0

再検討して IIS を使用してホストすると、構成ファイルの 1 行で ASP グローバル、アプリケーション、およびセッション オブジェクトを使用できるようになることがわかります。このトリックは、ASP アプリケーションと WCF サービスの間でセッション状態を共有できることを意味するため、非常に便利です。

于 2009-09-04T03:33:27.970 に答える
0

DBオプションはいいですね。パフォーマンスの問題がなければ、機能するはずのシンプルなデザインです。半リアルタイムで非永続的である余裕がある場合、1 つの方法は、各サービスのメモリにリストを保持し、新しいユーザーが参加したときに各サービスが他のサービスを更新することです。これは、集中型サービスを介して、または msmq などを使用して、ある種のブロードキャストとして実行できます。

于 2009-09-04T02:53:59.750 に答える