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;

由于此字典将在两个 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);
                }
            }
        }
    }
}

鉴于您不希望用户为特定服务列出两次,将 替换为 可能是有意义List<string>HashSet<string>

于 2009-09-04T03:11:24.020 回答
1

数据库似乎提供了一个持久性存储,它可能对您的应用程序有用或重要。此外,它还支持可能对您有用的交易等。大量更新可能是性能问题,但这取决于确切的数字、查询模式是什么、使用的数据库引擎、位置等。

此选项的替代方案可能是某种内存缓存服务器,例如 memcached。虽然这可以以与数据库服务器类似(某种)的方式共享和访问,但有一些警告。首先,这些平台通常没有某种永久存储支持。当 memcached 服务器死机时会发生什么?其次,它们可能不够符合 ACID 标准,无法供您使用。在添加和更新方面在负载下会发生什么?

于 2009-09-04T02:12:57.880 回答
1

我喜欢记忆中的方式。实际上,我正在为我现在正在工作的一个项目设计相同的机制。这适用于您没有机会访问数据库或某些人真的不愿意创建表来存储简单信息(例如针对机器名称的用户列表)的情况。

只有更新我才会有一个节点只会将其可用用户的列表返回给它的对等点,并且对等点会将其与其现有列表结合起来。然后将其现有列表返回给调用的对等方。这就是所有对等点如何与同一个列表同步的方式。

于 2011-08-11T03:34:12.840 回答
0

If you reconsider and host using IIS you will find that with a single line in a config file you can make the ASP Global, Application and Session objects available. This trick is also very handy because it means you can share session state between an ASP application and a WCF service.

于 2009-09-04T03:33:27.970 回答
0

DB 选项听起来不错。如果没有性能问题,那么它应该是一个简单的设计。如果你能负担得起半实时和非持久性的一种方法是在每个服务的内存中维护列表,然后每个服务在新用户加入时更新另一个。这可以通过集中式服务或使用 msmq 等作为某种广播来完成。

于 2009-09-04T02:53:59.750 回答