WCF使用net.tcp协议的性能表现

6
我有一个使用内置ServiceHost托管的WCF net.tcp服务,在进行一些压力测试时,我遇到了奇怪的行为。第一次发送一堆请求时,5到10个请求会很快得到响应,其余的则在大约2秒的间隔后返回。第二次发送请求时,10到20个请求会很快得到响应,其余的则在2秒的间隔后返回。
以上情况会一直重复,直到我能够快速地得到超过100个请求的响应,但如果我等待一分钟左右,服务的内存使用量就会下降,请求的返回速度就会恢复到5-10个迅速返回。
我正在测试的服务有一个小延迟,这样我就可以同时获得许多开放的连接,如果去掉这个延迟,请求会非常快地返回,可能同时只有2-5个连接是打开的。这个延迟是为了模拟数据库连接和其他出站操作。
从行为上看,它似乎是ServiceHost在分配某些东西,线程,类实例,但我无法弄清楚它是什么。
我可以在客户端中设置一个定时器,调用服务以保持其工作,但这似乎是一个不好的解决方案。
如果我对服务进行高持续负载,则所有请求都会迅速处理,但如果我有一个低活动期,然后涌入连接,则服务将变慢。
我的问题是:在WCF服务高负载下分配了什么,以及如何配置服务以预分配更多被分配的东西。
编辑: 我进行了更多测试,并查看了进程的任务管理器,当ServiceHost“休息”时,有10个线程打开,但当我开始发送请求时,线程计数会增加。只要线程计数很高,ServiceHost就可以快速处理传入的请求,但如果我暂停发送请求,则打开的线程计数减少,随后的请求开始花费更长的时间来处理。
现在,我该如何告诉ServiceHost保持一堆线程打开?或者比默认值10-12更多?
4个回答

6

经过大量的谷歌搜索,似乎问题出在线程池上。CLR线程池会分配一些线程,当它们被使用时,会限制新线程的创建,并在一段时间后回收未使用的线程。

有一些关于ThreadPool没有遵守SetMinThreads调用的bug的混淆。

http://www.michaelckennedy.net/blog/PermaLink,guid,708ee9c0-a1fd-46e5-8fa0-b1894ad6ce0f.aspx

我不确定这个错误是否已经解决,因为当我修改线程池设置时,问题仍然存在。

1

你提到的错误已在.NET 3.5 SP1中修复。这可能与问题有关,但我认为更有可能(远比线程更有可能)是限流是你的问题,就像Maurice所指出的那样。

<system.serviceModel>
  <service name="???" >
   <endpoint ... />
  </service>
</system.serviceModel>

这个“空”的配置限制了什么?10个会话,16个并发调用!请注意。

以下是关于线程的更多信息: http://www.michaelckennedy.net/blog/2008/08/20/ThreadPoolBugInNET20SP1IsFixed.aspx


1
决定同时处理多少请求的事情是ServiceThrottlingBehavior。有许多不同的阈值将限制正在处理的请求量。这也取决于您使用的绑定,例如wsHttpBinding默认为会话,而basicHttpBinding不使用会话,并且默认会话限制为10没有问题。
有关更多详细信息,请参见http://msdn.microsoft.com/en-us/library/ms735114.aspx

谢谢,我检查了这个网站,那里的设置已经在我的配置文件中,限制很高,应该能够一次性处理所有传入的连接,而不是先处理5-10个,然后每2秒处理一个。 - Kim

0
这感觉像是一个hack,但它似乎解决了你的问题。问题在于线程池需要时间来启动新线程,所以你真正需要的是等待待命的线程。为你的服务添加一个构造函数,并设置你想要的最小线程数。
  public YourService()
    {
        int workerThreads;
        int portThreads;
        ThreadPool.GetMinThreads(out workerThreads, out portThreads);
        ThreadPool.SetMinThreads(200, portThreads);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接