【问题标题】:WCF Service for many concurrent clients and database access用于许多并发客户端和数据库访问的 WCF 服务
【发布时间】:2010-01-22 11:13:03
【问题描述】:

我是 WCF 服务的新手,想知道解决以下问题的最佳方法是什么。

我有很多客户(约 200 - 约 500 个)在工作日期间都相当频繁地向我提出服务请求。大多数请求都涉及询问底层数据库以反馈正确的响应。

我关心的是传入请求产生的潜在数据库连接数。如果所有客户端同时发出请求,那么数据库服务器将受到重创。如果可能的话,我想避免与数据库建立大量的连接。

最好限制与 WCF 服务的并发连接数,从而无意中减少可能的数据库连接数?

我已经考虑过让服务成为一个单例,它会产生线程来执行数据库事务,这样我就可以控制线程的数量,但这是否有点矫枉过正,并且限制与服务的连接就足够了?

非常感谢您的建议。

【问题讨论】:

  • 考虑 WCF 缓存怎么样。

标签: c# database wcf


【解决方案1】:

正如 Marcos 已经提到的 - WCF 具有内置的服务限制功能,您可以在服务器上对其进行调整。这可以防止您的数据库服务器一次被过多的请求淹没。

默认为:

<serviceThrottling 
      maxConcurrentCalls="16"
      maxConcurrentSessions="10" 
      maxConcurrentInstances="26" />

有关详细信息,请参阅MSDN docs on ServiceThrottlingBehavior

这意味着 WCF 最多同时处理 16 个调用 - 也就是说,如果您的 WCF 服务类允许同时有多个调用者!

与 Marcos 不同,我建议将您的 WCF 服务类设为单例。常见的最佳实践是拥有一个简单的 WCF 服务类,并以每次调用的方式使用它——例如每个传入的请求都将获得自己的、完全独立的、新创建的 WCF 服务类实例 - 最多由服务限制行为定义并由 WCF 运行时控制。

如果您将 WCF 服务类设为单例,则必须将其 ConcurrencyMode 设置为 Multiple - 但是您需要格外小心,不要让类中的两个同时线程更改彼此下的相同值;多线程安全编程是一大挑战!或者您没有将并发模式设置为 Multiple,但是您的唯一一个 WCF 服务类实例只能以串行方式处理请求,一次一个 - 不是很可扩展!

每次调用和每个请求一个服务实例绝对是更简单的方法。通过适当的服务节流和 ADO.NET 连接池,可以打造一个非常强大且行为良好的环境!

有关更多详细信息,请参阅Dan Rigsby's excellent blog post on WCF service throttling

【讨论】:

  • 谢谢马克。有了 Rubens 和您的帖子,我更有信心不会使数据库过载,并且可以在这方面为最终用户提供更多控制。
【解决方案2】:

如果你使用ADO连接你的数据库,它应该提供连接池机制,所以你不需要处理这个。

请阅读本文了解更多信息:ADO.NET Connection Pooling at a Glance

【讨论】:

  • 谢谢鲁本斯,我将配置我的连接设置并对我的服务进行压力测试。
  • 你好@Andy,我在这里看到了所有的帖子,对我真的很有帮助。你能告诉我如何对服务进行压力测试吗?有什么软件吗?
【解决方案3】:

我们有一个类似的场景,我们只使用从我们的 WebService 到 DB 的一个连接并使用来自 SqlServer 的 MARS 来解决它,它可以完美且非常快速地运行。 Sql Server 真的知道如何处理你不必考虑的并发查询。

您可以避免打开和关闭连接的开销(显然连接池在这种情况下会有所帮助)

请记住在您的网络服务中添加如下内容:

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

在配置中:

<serviceThrottling maxConcurrentCalls="100"
 maxConcurrentSessions="100" 
 maxConcurrentInstances="100" />

这个选项在里面

  <behaviors>
      <serviceBehaviors>
        <behavior name="...">

希望这会有所帮助:)

【讨论】:

  • 我不认为 InstanceContextMode=Single 是一个很好的主意 - 它使您的服务类成为单例,因此是一个潜在的坏坏瓶颈。我永远不会那样做。限制行为本身就足以防止过多的并发数据库连接。
  • 对我们来说单例是完美的,如果你的代码没有任何锁,让它在同一个对象上运行有什么问题?事实上,我们避免在每次调用时创建服务对象,并且在压力测试中,我们使用单例获得了更好的性能。我们的服务仅在数据库上执行 SELECT 查询,我们没有看到任何单例给我们带来问题的场景。使用您的解决方案只能同时处理 16 个或 10 个查询,让 Sql Server 处理 100 个或更多有什么问题?为了避免这种情况,查询必须非常昂贵。
  • 这实际上正是我需要的建议。我有一个由资源有限的 Windows 服务托管的 WCF 服务,我想自己同步对这些资源的访问。 “多个”并发设置是我所缺少的。谢谢。
  • 很多人都远离 Singelton 模式。如果业务逻辑中没有锁定/并发(关键部分)代码,我宁愿建议/推荐使用单例模式。单例将避免不必要的创建(实例化)/垃圾收集到 CLR。​​
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
相关资源
最近更新 更多