WCF使用WSHttpBinding时在服务器上并发请求堆积 [英] WCF Concurrent requests piling up on the server when using 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.
- Note: setting
- 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 usingWSHttpBinding
? - 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屋!