代码之家  ›  专栏  ›  技术社区  ›  Shane Fulmer Lasse V. Karlsen

客户机-服务器体系结构问题

  •  1
  • Shane Fulmer Lasse V. Karlsen  · 技术社区  · 14 年前

    我在一个客户机-服务器系统上工作,遇到了多个客户机同时执行一个操作的问题。我们可以通过锁定代码的关键部分来解决这个问题,这可以确保第一个客户机在第二个客户机进入代码块之前完成操作。我的问题是:我们的服务器也是群集的,因此可以存在服务器本身的多个实例,这会重新创建与以前相同的问题。我们如何解决这个问题? 谢谢!

    扩展问题:第一个用户正在检查操作是否有效,并得到“是”响应。第二个用户正在检查某个操作是否有效,并且在第一个用户完成其操作之前也会得到“是”响应。但第一个用户的操作应使第二个用户的操作无效。问题是检查几乎同时发生在每个用户身上。

    2 回复  |  直到 14 年前
        1
  •  1
  •   John Saunders    14 年前

    听起来你的设计不好。如果可能的话,您的服务不应该保持状态。这样,就没有共享的状态可以继续。

    如果您必须保持状态,那么您必须将对该共享状态的所有访问都联锁起来。您可以使用C中的“lock”关键字进行以下操作:

    private static object _stateLocker = new object();
    private static int _someSharedState = 0;
    
    public void SomeAction()
    {
        lock (_stateLocker)
        {
            _someSharedState ++;
        }
    }
    
    public int GetValue()
    {
        lock (_stateLocker)
        {
            return _someSharedState;    }
    }
    
        2
  •  1
  •   LBushkin    14 年前

    关于您的特定问题的更多细节将有助于获得一个好的解决方案——但是,听起来您需要某种形式的进程间/跨服务器锁定。在.NET框架(或win32 API)中没有任何东西可以让这个过程简单化——恐怕你必须推出自己的解决方案。

    您可能希望研究某种集群队列机制,以便只有一个进程/线程正在执行一个操作。这在您的总体设计和您试图解决的问题中可能很容易,也可能不容易。或者,您可以使用中央授权(如数据库)和锁定结构来确定特定操作的锁是否已经启动。存在的问题是,由于需要不断地与数据库交互,很难使这样的解决方案能够很好地扩展。

    您可能拥有的另一个选项是允许多个进程尝试同时处理同一个操作,但只允许一个操作完成。这可能很难确保——但执行额外的工作并将其扔掉的成本(计算上)要比经常检查其他人是否已经在做这项工作的成本更低。