我有一个 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 秒的请求返回(这种情况很少见)。
    • 笔记:环境 <add address="*" maxconnection="100"/> 在客户端的 app.config 中使这种情况(似乎)停止发生。
  • 请求 B 立即发送并收到响应,而请求 C 则被推迟到 20 秒完成(这种情况很少见)

这是 fiddler 演示该问题的时间表:(点击查看大图)

正如您所看到的,请求都在服务器上备份。一旦 20 秒的请求完成,响应就会蜂拥而至,但请注意,有一些请求 不是 被拦住……

所以, 问题:

  • 这到底是怎么回事?为什么使用它可以正常工作 NetTcpBinding 并且不能使用 WSHttpBinding?
  • 为什么行为不一致?
  • 我能做什么来修复它?

笔记:

  • 它没有锁定服务器。我已经设置了断点并使用了 !syncblk 并且它始终报告没有锁定。
  • 这不是我的线程(否则 NetTcpBinding 不应该工作)
  • 我有 <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> 在服务器的app.config中设置
  • 20 秒的调用只是在等待计时器,它不会对 CPU、磁盘或网络造成影响
  • 我更喜欢一个不涉及重新架构应用程序以使用异步调用的解决方案......这是一大堆遗留代码,我真的不想弄乱我不理解的东西。
有帮助吗?

解决方案 3

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

最终我还是没能解决这个问题。
我们的最终解决方案是将我们的应用程序从 WSHttpBinding 并到 NetTcpBinding 在生产中 - 出于性能原因,我们一直计划最终这样做。

但这是相当不幸的,因为它留下了一个黑色印记 WSHttpBinding 这可能有也可能没有。如果有人确实想出了一个不涉及放弃的解决方案 WSHttpBinding,我很想知道

其他提示

WCF(.Net 或 Windows 的东西)之外有一些限制,默认只允许最多两个同时出站 HTTP 连接。不幸的是,我一辈子都不记得这个东西的名字(以及你在 app.config 或你的应用程序中放置的内容来覆盖它)。鉴于您没有看到请求离开客户端,并且它只是 HTTP,我认为您遇到了“那个问题”。我会继续寻找它的名字。

更新:找到它 - 在客户端上尝试这个(但将“2”更改为更大的数字):

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

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

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

网页配置:<system.web> <sessionState mode="Off" /> </system.web>

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

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

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

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

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

如果换成BasicHttpBinding,还能用吗?

是这样吗,听起来像 这是你的问题, ,会话限制,这让我很恼火。

考虑使用ContrencyMode.Multiple在每个通话服务上以允许并发呼叫。

我忘了——可以订购吗?我认为也许 RM 通过 http 保留顺序,但也许 Tcp 会话不保留顺序(除非您明确请求它)?服务合同上是否有一个属性描述了有序/无序会话(我忘记了)。

不确定,但有时 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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top