【问题标题】:Lots of database access makes a WCF service unresponsive大量数据库访问使 WCF 服务无响应
【发布时间】:2012-05-21 17:20:28
【问题描述】:

我有一个 WCF 双工服务(使用 net.tcp 绑定进行会话实例化),它可能会执行大量数据库访问。当它进入其高 db 访问例程时,它对任何 WCF 服务调用都没有响应。

我检查了 CPU 利用率,虽然很高,但不是 100%。这是在一个 4 芯盒子上。

WCF 似乎没有处理任何实际请求。不仅没有调用服务操作,而且在 WCF 堆栈的下方还有一些安全自定义行为也没有被调用。这让我觉得 WCF 不知何故缺乏线程,因此无法分配新线程进行访问。

我不认为这是一个限制问题,因为当服务的当前会话数很少(少于 5 个)时,我可以做到这一点。

有问题的数据库操作是数以千计的单行插入。这是通过每 500 次调用处理和重构的单个实体框架上下文来完成的,以减少实体框架内部缓存的内存积累。目标数据库是 SQL Express 2008 R2。

此服务中有相当数量的工作线程。所有这些都由任务并行库实例化......一些是常规的短期任务(使用 CLR 线程池),另一些是长时间运行的任务(获得自己的 CLR 线程),但这些都不是 I/O 线程(除非 CLR 正在做一些我不知道的魔法)。数据库写入发生在一个长时间运行的任务上。

是否有任何 WCF 或调试诊断工具可以报告或可视化 WCF 线程、工作线程、I/O 线程和 WCF 限制的当前状态?

环境总结

  • WCF 服务托管在 Windows 服务中
  • WCF 服务使用 net.tcp 双工绑定
  • WCF 服务基于会话(双工合同要求)
  • Windows 服务只有一个实例,但 WCF 服务对象的多个实例会根据 WCF 的要求进行实例化。
  • WCF 服务操作可快速将工作委派给在 Windows 服务中持久存在的后台线程。所有 WCF 操作都会快速返回,然后将后台线程生成的附加结果沿 WCF 双工回调通道传递。
  • 所有数据库访问都在后台工作线程上完成。没有 WCF 线程用于长时间运行的工作。
  • WCF 服务有一个自定义安全行为。没有其他行为(例如可靠的消息传递等)

【问题讨论】:

  • 配置了任何额外的行为吗?可靠的消息传递或类似的东西?是否涉及交易?
  • 没有可靠的消息传递或交易。唯一的自定义行为是自定义安全处理程序。查看此错误的一种方法是在调试器中运行服务并在安全处理程序中放置断点。通常,如果客户端尝试连接,这会很快触发。当在这个 DB thrash 中时,安全处理程序永远不会执行,这表明(在我看来)WCF 缺乏线程。

标签: multithreading wcf entity-framework


【解决方案1】:

如果您使用会话实例化,则每个客户端连接都有一个主机服务。如果主机正在访问数据库,那么我会说它正在阻塞并且在完成之前将无法处理来自其客户端的任何其他调用。您也许可以将其工作方式更改为异步。调用 start 方法在工作线程上启动数据库活动并立即返回。要么有一个检查状态的进度方法,要么因为您使用的是双工,所以在完成时让主机向客户端发出信号。

还是 wcf 服务不接受新客户端?

【讨论】:

  • WCF 服务托管在持久性 Windows 服务中。 Windows 服务具有定期唤醒并执行数据库工作的后台线程。 WCF 服务是基于会话的,并且为每个新客户端创建一个新的会话实例。这工作得很好。除非 Windows 服务在后台执行大量数据库工作,否则 WCF 服务永远不会被实例化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多