创建WCF Restful服务,同时性问题

5

你好,我正在使用WCF创建一个RESTful服务,该服务可能会被同时至少500人使用。为了应对这个情况,我需要设置什么样的参数呢?请给我一些提示和建议,谢谢。

以下是我目前所拥有的样例;

[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 

这是一个方法被调用的例子:

    public UsersAPI getUserInfo(string UserID)
    {
        UsersAPI users = new UsersAPI(int.Parse(UserID));

        return users;
    }



    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, UriTemplate = "User/{UserID}")]
    [WebHelp(Comment = "This returns a users info.")]
    UsersAPI getUserInfo(string UserID);
1个回答

7
最佳的方法是使用:
  • InstanceContextMode.PerCall
  • ConcurrencyMode.Single
这将为每个调用者创建一个服务类的新实例,并使您不必担心多线程并发访问您的代码,因为每个请求都会得到它自己的服务类实例(它本身是单线程的-它一次只为一个调用者提供服务)。
此外,采用这种方法,您可以轻松地“横向扩展”,例如,只需添加更多服务器来处理更高的负载(位于您位置或在“云”中,例如Windows Azure工作者)。
使用ServiceThrottling服务行为,您可以非常容易地控制允许的并发调用者数量-这取决于您的计算机类型和大小。
<serviceBehaviors>
  <behavior name="Throttling">
     <serviceThrottling 
             maxConcurrentCalls="16"
             maxConcurrentInstances="16"
             maxConcurrentSessions="10" />
  </behavior>
</serviceBehaviors>

这些是WCF 3.5的默认设置 - maxConcurrentCalls设置定义了同时可以处理多少个调用者。

查看MSDN关于服务限制的文档以获取更多详细信息。


嗨,感谢您的回复。如果我们发展壮大,拥有了像30000个用户这样的规模,是否仍然适用相同的设置? - pmillio
+1,好答案。使用上面的设置,如果您在服务实例外访问共享状态,仍需要关注线程安全性。此外,如果您不将可变状态存储在服务实例中,则可以使用 InstanceContextMode.SingleConcurrencyMode.Multiple 来获得最佳性能。 - Allon Guralnek
1
@pmillio:你可能需要增加maxConcurrentCalls的数量(这只是默认值),或者你可能需要购买额外的服务器——但是这种架构非常适合扩展。 - marc_s
@Allon Guralnek:一个数据库通常会很好地处理这些并发问题,这就是为什么任何服务都应该将它们的状态存储在数据库中,并尽量避免使用任何其他共享状态的存储(这会变得混乱且难以正确处理)。 - marc_s
我在谈论对象中的共享状态(例如静态引用、缓存、第三方组件等外部依赖项)。这些有时是不可避免的,因此应该小心处理。我认为只有非常简单的应用程序才能够忽略线程安全性。此外,通常不希望因为同步短暂的共享状态而产生数据库往返的性能损失。 - Allon Guralnek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接