28

我有一个 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 秒长的请求之前不会处理它们

但有时候:

  • 在 20 秒的请求返回之前(这种情况很少见) ,请求 B 和 C不会被发送(它们甚至不会出现在 fiddler 中)。
    • 注意:<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、磁盘或网络
  • 我更喜欢不涉及重新构建应用程序以使用异步调用的解决方案......这是一大堆遗留代码,我真的不想弄乱我不理解的东西。
4

8 回答 8

11

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

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

<configuration>
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "2" />
    </connectionManagement>
  </system.net>
</configuration>
于 2009-05-07T04:35:20.633 回答
4

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

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

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

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

于 2011-06-30T08:08:07.777 回答
2

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

最后,我从来没有设法解决这个问题。
我们最终的解决方案是将我们的应用程序从生产环境切换WSHttpBindingNetTcpBinding生产环境——出于性能原因,我们一直计划最终这样做。

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

于 2009-09-21T20:56:06.887 回答
2

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

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

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

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

于 2011-06-30T08:24:54.327 回答
1

如果改成BasicHttpBinding,能用吗?

是这样,听起来这是你的问题,会话节流,让我大吃一惊。

于 2009-05-08T03:35:27.400 回答
1

考虑在每次调用服务上使用 ConcurrencyMode.Multiple 以允许并发调用。

于 2011-01-09T06:54:14.990 回答
0

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

于 2009-05-08T03:25:47.797 回答
-1

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

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
于 2015-01-02T07:23:30.187 回答