使用WSHttpBinding时,WCF并发请求在服务器上堆积

时间:2009-05-07 04:21:16

标签: wcf multithreading concurrency throttling

我有一个WCF客户端/服务器应用程序,它使用WSHttpBinding通过HTTP进行通信。

服务器设置:自托管,使用标准WCF ServiceHost。 我的实际服务类别归结为:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
 InstanceContextMode = InstanceContextMode.PerSession, 
 UseSynchronizationContext = false)]

客户端设置:使用Visual-studio生成的客户端代理,使用同步服务调用(proxy.call_server_method阻止,直到服务器完全响应为止。 )

方案: 我有一个特定的方法调用,在服务器上执行需要20秒。客户端在一个单独的线程中调用此方法,因此它不会被阻止,ConcurrencyMode.Multiple表示WCF也应该在服务器上的一个单独的线程中执行它。

当我将我的应用配置为使用NetTcpBinding时,一切正常。

支持这一理论。

问题
如果我将应用配置为使用WSHttpBinding,则此长方法调用会导致http请求“备份”。我已经通过检查我的日志和使用fiddler调试HTTP请求来验证这种行为。

示例:

  • 客户端在后台线程上发起20秒长请求
  • 客户端在前台线程上启动请求B和C
  • 请求B和C被发送到服务器,在完成20秒长请求之前,服务器不处理它们

但有时候:

  • 请求B和C 不会被发送(它们甚至不会出现在fiddler中),直到20秒请求返回(这种情况很少见)。
    • 注意:在客户端的app.config中设置<add address="*" maxconnection="100"/>会使此(似乎)停止发生。
  • 请求B被立即发送并收到响应,而请求C被保留,直到20秒完成(这是罕见的)

以下是小提琴手演示问题的时间表:(点击查看大图)

如您所见,请求都在服务器上备份。一旦20秒的请求完成,响应全部涌入,但请注意,有些请求被阻止......

所以,问题

  • 这到底是怎么回事?为什么使用NetTcpBinding并且无法使用WSHttpBinding
  • 工作正常
  • 为什么行为不一致?
  • 我该怎么做才能解决它?

注意:

  • 它没有锁定服务器。我设置了断点并使用了!syncblk,并且它一直报告没有锁定。
  • 这不是我的线程(NetTcpBinding不应该工作)
  • 我在服务器的app.config
  • 中设置了<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
  • 20秒的通话只是等待一个计时器,它不会颠覆CPU或磁盘或网络
  • 我更喜欢一种不涉及重新设计应用程序以使用异步调用的解决方案...这是一大堆遗留代码,我真的不想搞乱我不理解的东西

8 个答案:

答案 0 :(得分:11)

WCF(.Net或Windows事件)之外有一些限制,默认只允许最多两个同时出站HTTP连接。不幸的是,我不记得我生命中的事物的名称(以及你在app.config或你的应用程序中覆盖它的内容)。鉴于你没有看到请求离开客户端,并且它只是HTTP,我认为你正在打“那件事”。我会继续寻找它的名字。

更新:找到它 - 在客户端上尝试此操作(但将'2'更改为更大的数字):

<configuration>
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "2" />
    </connectionManagement>
  </system.net>
</configuration>

答案 1 :(得分:4)

我们在IIS / ASP.NET中托管的JSON服务看到了完全相同的症状。

根本原因最终是ASP.NET同步请求 - 而不是WCF。我们必须禁用会话状态(在应用程序级别)以获取并发WCF方法。

的Web.config: <system.web> <sessionState mode="Off" /> </system.web>

请注意,我们的服务使用webHttpBinding,而不是wsHttpBinding。所以,我不确定这是否也解决了猎户座的问题。

答案 2 :(得分:2)

[自我回答向其他用户展示我们的最终解决方案]

最后,我从未设法解决这个问题 我们的最终解决方案是将我们的应用从WSHttpBinding转移到生产中的NetTcpBinding - 我们一直计划最终出于性能原因这样做。

这是相当不幸的,因为它在WSHttpBinding上留下了一个黑色标记,可能会或可能不会被保证。如果有人提出的解决方案不涉及放弃WSHttpBinding,我很想知道它

答案 3 :(得分:2)

我认为您达到了协议限制并且要解决它,您需要修改客户端计算机上的标准设置:

http://support.microsoft.com/kb/183110

http://support.microsoft.com/kb/282402

我猜WSHttpBinding在发出请求时使用WinINET设置。

答案 4 :(得分:1)

如果更改为BasicHttpBinding,它是否有效?

是这样,听起来像是this is your problem,会话节流,让我陷入困境。

答案 5 :(得分:1)

考虑在每个呼叫服务上使用ConcurrencyMode.Multiple以允许并发 调用

答案 6 :(得分:0)

我忘记了 - 它可以订购吗?我想也许RM over http可以保留顺序,但也许Tcp会话不会(除非你明确要求它)?服务合同中是否有描述有序/无序会话的属性(我忘了)。

答案 7 :(得分:0)

不确定但有时来自silverlight应用程序的并发调用的问题与浏览器连接管理有关。对我来说,解决方案是将它放在我们的App.xaml.cs,Application_Startup方法中,如下所示:http://weblogs.asp.net/olakarlsson/simultaneously-calling-multiple-methods-on-a-wcf-service-from-silverlight

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);