企业服务器 WCF 压力/线束测试
我写这封信是为了询问有关 WCF 性能的问题。
1.背景
我们有一个在 .NET 3.5 上运行的客户端-服务器系统。服务器是C# 服务,客户端是silverlight 应用程序。
我编写了一个压力测试器,它是一个 winforms 应用程序,工作原理如下:
- 它生成工作进程
- 工作进程触发不同的工作进程 应力载荷
[例如 (i=0;i<100;i++) Send(payload)]
- 该服务正在运行 <代码>[ServiceBehavior(InstanceContextMode =InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Single)]。
- 所有超时(操作、发送 receive,..) 已设置为最大
- 服务限制: maxConcurrentSessions="200"
- 消息跟踪已启用并打印 一切
2。问题
在达到一些阈值(取决于压力测试负载和测试环境)后,我的工作进程(正常的 .NET 3.5 C# 控制台应用程序)开始抛出异常。我最初遇到了 timeoutExceptions,但经过大量阅读和处理后,我得到了超时异常。调整会话我只得到两个异常(仅在非常高的负载下)
- 底层连接已关闭: 预期的连接 keepalived已被服务器关闭。
- 接收时发生错误 HTTP 响应 .这可能是由于 到服务端点绑定不 使用HTTP协议。这可以 也可能是由于 HTTP 请求 上下文被服务器中止 (可能是由于服务关闭 向下)。查看服务器日志了解更多信息 详细信息。
除此之外,我还可以看到大量的消息丢失。服务器永远不会失败(这很好)。我认为服务器只是拒绝它无法处理的消息。
3.采取的行动
我已经阅读了很多文章并调整了很多参数(包括限制、超时等)。例如,我已经尝试了这里的所有建议: http://www.codeproject.com /KB/WCF/WCFThrotdling.aspx
我确实获得了性能改进,但根据我运行服务器的环境,我将达到此上限并开始拒绝邮件。
跟踪日志中根本没有报告任何错误
4。理想情况下...
...我希望服务器随着负载的增加而变慢,但不会错过消息。 (即,如果有 500 个其他人正在使用该服务,则客户端需要 10 秒才能获得回复,这是可以的)
在 WCF over Http 和单线程、单上下文服务下这可能吗?我是否缺少此处的设置,或者是否达到了上限并获得了预期的 WCF 行为?
注意:我已尝试使用 ConcurrencyMode.Multiple
。我确实得到了改进(即需要更多负载才能达到上限),但我确实遇到了相同的异常。
I am writing in order to ask a question on WCF performance.
1. Background
We have a client-server system that runs on .NET 3.5. The server is a C# service and the client is a silverlight app.
I have written a stress tester that is a winforms app and works like that:
- It spawns worker processes
- The worker processes fire different
stress loads[eg for (i=0;i<100;i++)
Send(payload)] - The service is running as
[ServiceBehavior(InstanceContextMode
.
=InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)] - All the timeouts (operation, send
receive,..) have been set to maximum serviceThrottling:
maxConcurrentSessions="200"- message tracing is enabled and prints
everything
2. The Issue
After some thresholds(dependent on the stress test loads and the environment under test) my worker processes (normal .NET 3.5 C# console apps) begin to throw exceptions. I was getting timeoutExceptions initially but after a lot of read & tweak sessions I got to a point where I get only two exceptions (only under very high load)
- The underlying connection was closed:
A connection that was expected to be
kept alive was closed by the server. - An error occurred while receiving the
HTTP response to . This could be due
to the service endpoint binding not
using the HTTP protocol. This could
also be due to an HTTP request
context being aborted by the server
(possibly due to the service shutting
down). See server logs for more
details.
Alongside with that I can see substantial message loss. The server never fails(which is good). I think the server is simply rejecting messages it cannot handle.
3. Actions Taken
I have read a lot of articles and tweaked a lot of parameters(including throttling, timeouts, etc). For example I have tried all of the sugggestions here: http://www.codeproject.com/KB/WCF/WCFThrottling.aspx
I do get performance improvement but depending on what environment I am running the server I will hit this upper limit and start having messages rejected.
No errors at all are reported in the trace logs
4. Ideally...
...I would want to have a server that gets slower as load increases, but does not miss messages. (ie its ok if a client takes 10 secs to get a reply if 500 others are using the service)
Is this possible under WCF over Http and a single-threaded, single context servive? Am I missing a setting here or am I hitting an upper bound and getting the expected WCF behaviour?
NB: I have tried using ConcurrencyMode.Multiple
. I do get an improvement (ie more load is needed to hit the upper bound) but I do hit the same exceptions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最好的选择是使用 netMsmqBinding。 如果您不熟悉,这里是其工作原理的概述。此绑定将允许您的服务使用 MSMQ 对超额负载进行排队,以便消息不会丢失。这应该可以解决你的问题。
Your best option would be to use the netMsmqBinding. Here is an overview of how it works if you're not familiar. This binding will allow your service to queue the excess load using MSMQ, so that messages will not be lost. This should solve your problem.
我想我“找到”了我的答案!
我将在这里解释一下我做了什么,以防其他人遇到这个问题。
首先,您可以检查未完成的呼叫计数器,它类似于 T*CP 积压*。
此外,在perfmon中可以看到有多少调用正在同时处理,以及有多少调用正在排队。
这两个指标让我确认我确实已经达到顶峰了。因此,我需要在消息传递时发送/接收一些 ACK 的代码。幸运的是 MS 已经为我们做到了这一点!它被称为可靠的 WCF 消息传递。
http://msdn.microsoft.com/en-us/library/ms730123.aspx
http://msdn.microsoft.com/en-us/library/aa480191.aspx
通过实现 WsHttpBinding,服务器可以应对之前失败的负载。此外,服务器能够处理的负载是以前的两倍。
显然存在性能开销,但确实可靠。
太好了,所以我想现在我找到了解决方案,我可以告诉用户所有这些奇妙的东西都在那里,但他们不会得到任何东西,因为他们的客户端运行在 silverlight 3 上,而 Silverlight 3 没有可靠的解决方案WCF 实现...耶!
I guess I 'found' my answer!
I will explain here what I did in case someone else bumps into this one.
First of all you can check the Calls Oustanding counter, which is something like a T*CP backlog*.
In addition in perfmon can see how many calls are being handled concurrently, and how many are queued.
These two indicators allowed me to validate that indeed I was hitting the roof. Therefore I needed code that would send/rcv some ACKs upon messaging. Luckily MS have already done this for us! Its called reliable WCF messaging.
http://msdn.microsoft.com/en-us/library/ms730123.aspx
http://msdn.microsoft.com/en-us/library/aa480191.aspx
By implementing a WsHttpBinding the server could cope under loads where it previously failed. In addition the server managed to cope with loads twice as much as before.
Clearly there is a performance overhead but it is indeed reliable.
Great, so I guess that now that I found the solution I can tell to the users that all of that fantastic stuff is out there, but they ain't gonna get nothing of this because their client runs on silverlight 3 which does not have reliable WCF implementations...yey!
是否有特殊原因必须运行单例服务?除非您想与所有服务共享某些状态,否则我会完全避免它。单例的问题是它的状态可以被连接到它的多个工作线程中的任何一个更改,因此它必须同步访问以避免状态损坏。这是相当昂贵的,并且确保一次只有一个客户端可以访问单例。
如果您需要跨多个请求维护状态,请优先使用每次调用或会话。
Is there a particular reason why you have to run a singleton service? Unless you want to share some state with all your services I would avoid it altogether. The problem with singleton is that its state can be changed by any of multiple worker threads connected to it, so it must synchronise access to avoid state corruption. This is rather expensive and ensures that only one client can access the singleton at a time.
Prefer to use per-call, or session if you need to maintain state across multiple requests.
您还应该尝试调整 ASP.NET Thrapool 配置:http://support.microsoft.com/kb/821268< /a> 作为服务托管在 IIS 下。
问候,
阿米特·巴蒂亚
You should also try truning ASP.NET Threapool configuration: http://support.microsoft.com/kb/821268 as Service is hosted under IIS.
Regards,
Amit Bhatia