WCF使用WSHttpBinding时在服务器上并发请求堆积 [英] WCF Concurrent requests piling up on the server when using WSHttpBinding

查看:200
本文介绍了WCF使用WSHttpBinding时在服务器上并发请求堆积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



服务器设置:self-hosting标准的WCF ServiceHost
我的实际服务类归属为:

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

strong>:使用Visual Studio创建的客户端代理使用同步服务调用( proxy.call_server_method 阻塞,直到服务器完全响应。)



场景
我有一个特定的方法调用,需要20秒才能在服务器上执行。客户端在一个单独的线程中调用此方法,因此它不会被阻塞, ConcurrencyMode.Multiple 意味着WCF应该在服务器上的一个单独的线程中执行它。



这个理论支持的事实是,当我配置我的应用程序使用 NetTcpBinding ,一切正常。



问题

如果我将应用程序配置为使用 WSHttpBinding ,那么这个long方法调用会导致http请求备份。我已通过检查我的日志和使用fiddler调试HTTP请求来验证此行为。



示例:




  • 客户端在后台主题上发起20秒长请求

  • 客户端在前台主题上发起请求B和C

  • 请求B和C发送到服务器,它不会处理它们,直到完成20秒长的请求



但有时:




  • 请求B和C 未发送(他们甚至不会出现在提琴手),直到20秒请求回来(这是罕见的)。


    • 注意:设置< add address =*maxconnection =100/>


  • 请求B发送并立即接收响应,而请求



这是从fiddler演示问题的时间表:(点击更大版本)



< img src =http://farm4.static.flickr.com/3311/3510636841_18f9b2b0a1.jpg/>



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



所以,问题




  • 这是怎么回事?为什么使用 NetTcpBinding 而不能使用 WSHttpBinding

  • <为什么不一致的行为?
  • 我可以如何解决?



注意: / p>


  • 它不会在服务器上锁定。我设置了断点,并使用!syncblk ,它一贯报告没有锁被暂挂。

  • 这不是我的线程(NetTcpBinding shouldn否则会失效)

  • 我有< serviceThrottling maxConcurrentCalls =1000maxConcurrentInstances =1000maxConcurrentSessions =1000/> 在服务器的app.config中设置

  • 20秒钟的通话正在等待一个计时器,它不会颠覆CPU或磁盘或网络

  • 我喜欢一个不涉及重新构建应用程序以使用异步调用的解决方案...它是一大堆遗留代码,我真的不想搞乱我不明白的东西。


解决方案

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



最后,我从来没有设法解决这个问题。

我们的最终解决方案是将应用程式从 WSHttpBinding NetTcpBinding 在生产中 - 我们一直计划这样做最终无论如何性能的原因。



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


I have a WCF client/server app which is communicating over HTTP using the WSHttpBinding.

Server Setup: self-hosting, using the standard WCF ServiceHost. My actual service class is attributed as:

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

Client Setup: using a visual-studio generated client proxy using synchronous service calls (proxy.call_server_method blocks until such time as the server has responded in full.)

Scenario: I have one particular method call which takes 20 seconds to execute on the server. The client calls this method in a separate thread, so it is not being held up, and the ConcurrencyMode.Multiple means WCF should execute it in a separate thread on the server as well.

This theory is supported by the fact that when I configure my app to use NetTcpBinding, everything works fine.

Problem:
If I configure the app to use WSHttpBinding, then this long method call causes the http requests to 'back up'. I have verified this behaviour both from inspecting my logs, and by debugging the HTTP requests using fiddler.

Example:

  • Client initiates 20-second long request on a background thread
  • Client initiates request B and C on foreground thread
  • Requests B and C get sent to the server, which doesn't process them until it is done with the 20-second long request

But sometimes:

  • Requests B and C do not get sent (they don't even appear in fiddler) until the 20-second request comes back (this is rare).
    • Note: setting <add address="*" maxconnection="100"/> in the client's app.config made this (appear to) stop happening.
  • Request B gets sent and receives a response immediately, while request C is held back until the 20-second one completes (this is rare)

Here's a timeline from fiddler demonstrating the problem: (click for bigger version)

As you can see, the requests are all getting backed up at the server. Once the 20-second request completes, the responses all come flooding through, but note that there are some requests which aren't getting held up...

So, Questions:

  • What the heck is going on here? Why does it work fine using NetTcpBinding and not work using WSHttpBinding?
  • Why the inconsistent behaviour?
  • What can I do to fix it?

Notes:

  • It's not locking on the server. I've set breakpoints and used !syncblk and it consistently reports no locks are being held.
  • It's not my threading (NetTcpBinding shouldn't work otherwise)
  • I have <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> set in the server's app.config
  • The 20-second call is just waiting on a timer, it's not thrashing the CPU or disk or network
  • I'd prefer a solution that didn't involve re-architecting the application to use asynchronous calls... it's a big bunch of legacy code and I really don't want to be messing with stuff I don't understand.

解决方案

[Self-answer to show other users what our eventual solution was]

In the end, I never managed to solve this.
Our final solution was to switch our app away from WSHttpBinding and onto NetTcpBinding in production - we had been planning on doing this eventually anyway for performance reasons.

This is rather unfortunate though, as it leaves a black mark on WSHttpBinding which may or may not be warranted. If anyone does ever come up with a solution which does not involve ditching WSHttpBinding, I'd love to know about it

这篇关于WCF使用WSHttpBinding时在服务器上并发请求堆积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆