返回首页

{S0的}

Introductionnbsp;
上午9时在早晨,在繁忙的交通您的业​​务,你会得到你建立的网站是没有更多的紧急呼叫。它不会响应任何请求。有些人可以看到一些页面后等待很长一段时间,但最不能。所以,你认为它必须是一些缓慢的查询或数据库可能需要一些调整。你不喜欢的定期检查,寻找在CPU数据库服务器上的磁盘。你会发现没有什么不对劲的地方。然后你怀疑它必须Web服务器运行缓慢。所以,你检查网络服务器上的CPU和磁盘。你有没有发现问题。两个Web服务器和数据库服务器非常低的CPU和磁盘使用情况。然后,你怀疑它必须是网络。所以,你一个大的文件副本尝试从Web服务器到数据库服务器,反之亦然。不,文件的副本完全正常,网络也没有问题。您还可以快速检查内存所有服务器上使用,但发现RAM的使用是完全正常的。作为最后的手段,你运行一些诊断负载平衡器,防火墙,交换机,但发现一切都处于良好形状。但是,您的网站。回顾上的性能计数器Web服务器,你看到了很多入门排队的请求,并有非常高请求的执行时间,并要求等待时间。
{S}
所以,你做一个IIS重新启动。您的网站回来网上几分钟,然后再次下降。这样重启后几次你意识到它不是一个基础设施问题。你有一些在你的代码的可扩展性问题。所有您已阅读的好东西约可扩展性,并认为这些童话故事,他们将从未发生过,你现在发生在你面前。你意识到你应了你的服务异步。这里的问题是什么?
有高要求的执行时间。它意味着请求正在非常长的时间才能完成。也许你是外部服务消费是过于缓慢或下降。因此,线程没有得到释放同样的速度传入的请求进来,请求得到排队(因此在队列GT应用的要求; 0),并没有得到执行,直到某个线程从线程池中释放。
在N层应用程序可以有多个层服务。你可以有来自外部的服务消费数据服务。这是常见的Web 2.0应用程序的数据收集从各种互联网服务并在企业应用中,你在哪里组织的一部分到自己的应用程序,但提供一些服务,这些服务需要消耗由该组织的其他部分公开的其他服务。例如,你有交谈外部服务层使用WCF构建服务层可能或可能不是一个WCF服务层。
{S2的}
在这种架构中,你需要考虑使用异步服务,以获得更好的性能,如果你有大量的请求,说周围100请求/秒每台服务器。如果外部服务或通过广域网或互联网需要较长的时间来执行,然后使用异步服务不再是可有可无实现可扩展性,因为长时间运行的服务将耗尽线程NET线程池。从一个异步WCF服务调用另一个异步WCF服务很容易,你可以很容易地链中。但是,如果外部的服务是不是WCF和支持HTTP(例如,REST),那么它就会被悍然复杂。让我告诉你怎么可以链多个异步WCF服务和连锁纯香草HTTP服务与异步WCF服务。什么是异步的服务?
异步服务不占用线程,而这是做一些IO操作。你可以火象调用一个外部的异步IO操作外部Web服务,或触及某些HTTP URL或阅读一些文件异步。而IO操作发生时,线程,这是执行WCF请求被释放,以便它可以为其他请求。作为一个因此,即使外部操作时间长,返回的结果,你不占。NET线程池线程。这可以防止线程拥堵并提高您的应用程序的可扩展性。你可以阅读有关如何细节服务异步。简而言之,同步服务是我们通常做什么,我们只是调用服务等待它返回的结果。
{S3的}
在这里您的客户端应用程序调用你的服务,这在从而使一个外部服务调用获取数据。直到外部服务响应,服务器有一个线程占用。结果到达时从StockService,服务器将返回导致客户端和释放线程。
但是在异步的服务模式,服务器不等待外部服务返回的结果。它的发行权后,线程发射要求StockService。
{S0的}
正如你看到的图,只要服务器调用上StockService BeginGetData,它释放线程所代表的垂直框在服务器上的生命线。但是客户端还没有得到任何回应。客户仍在等待。 WCF将持有的请求,不返回任何响应但。当StockService完成其执行,服务器选择一个空闲线程来自ThreadPool,然后执行的代码在服务器的休息和返回的响应返回给客户。
这是如何工作的异步服务。显示我的服务
让我们来看看一个典型的异步WCF服务。说你有这项服务:

public interface IService

{

[OperationContractAttribute] string GetStock(string code);



} 

如果你想使这个异步,您将创建一个Begin和结束对。{C}
现在,如果你做了异步服务好老NET 2.0的ASMX服务,你知道,你可以得到它在几行完成。
public class Service : IService

{

 public IAsyncResult BeginGetStock(string code, AsyncCallback callback, object asyncState)

 {

  ExternalStockServiceClient client = new ExternalStockServiceClient();

  var myCustomState = new MyCustomState { Client = client, WcfState = asyncState };

                return client.BeginGetStockResult(code, callback, myCustomState);

 }

 public string EndGetStock(IAsyncResult result)

 {

  MyCustomState state = result.AsyncState as MyCustomState;

  using (state.Client)

   return state.Client.EndGetStockResult(result);

 }

} 

,但令人惊讶的,这并不WCF中的工作。你会得到从客户端此异常时,你将调用EndGetStock:{体C3}
对InnerException以及是完全无用的。{的C4}
你会发现,EndGetStock服务的方法从来没有被击中,但你怎么称呼它。
,它的工作原理完全正常,在良好的旧ASMX服务。我已经做了这么多次,创建异步Web服务。举例来说,我为了克服交叉使用ASMX已经建立了一个Ajax代理服务域的HTTP调用从Javascript的浏览器的限制。你可以阅读一下从这里获取代码。 WCF中的解决方案是无法想象的艰苦记得和令人难以置信的头扭理解。WCF异步服务是非常复杂
在WCF中,传统的异步模式不起作用因为如果你仔细研究代码,你会看到代码完全忽略传递的BeginGetStock方法"的AsyncState。{C5的}
旧ASMX和新的WCF之间的区别在于的AsyncState是空的,但不是在ASMXWCF的。的AsyncState有一个非常有用的对象它:
正如你所看到的MessageRpc这是负责管理请求的线程运行。因此,这是绝对重要的,我们随身携带的其他异步调用使最终的MessageRpc负责运行请求的线程,得到机会致电EndGetStock的。
下面的代码在WCF异步模式:{5233}
这是谁的代码很难理解调用谁和如何得到执行的回调。下面是一个序列图说明它是如何工作的:
{六}
这里有一个演练,这里发生了什么事情:
客户端,可以是一个WCF代理,使得调用WCF service.WCF运行(也许由IIS托管)拿起电话,然后从线程池中的线程并调用它BeginGetStock,传递一个回调在服务状态WCF stuff.The BeginGetStock方法,这是我们自己的代码,异步调用到StockService,这是另一个WCF服务。然而,这里不通过WCF回调和状态。在这里,它需要通过一个新的回调,将还以颜色的服务,以及一个新的状态,包含服务需要完成的东西,其EndGetStock通话。强制性的东西,我们需要的StockService的实例因为内部服务EndGetStock的,我们需要呼吁StockService StockService.EndGetStockResult.Once BeginGetStockResult,是调用时,它开始一些异步操作并立即返回服务IAsyncResult.The BeginGetStock收到的IAsyncResult,这包装,如果在一个MyAsycResult实例,并回到WCF runtime.After一段时间的回报,当异步操作,StockService启动完成后,它会引发回调,然后直接上的服务。回调触发WCF回调,这反过来又激发EndGetStock上Service.EndGetStock然后得到,从MyAsyncResult StockService的实例,然后调用上,它EndGetStockResult得到响应。然后它返回响应WCF的runtime.WCF运行比返回响应返回给客户端。这是非常困难的,它是非常困难做正确为几百方法。如果你有一个复杂的服务层他们呼吁许多其他服务和数百个业务,然后想象这么多的代码写为每个操作。
我想出了一种方法来减少疼痛使用代表和一些"代码反转呢??模式。下面是它的外观就像当你遵循这个模式:{C7-}
在这种方法中,所有的水暖工作,创建CustomAsyncResult,CustomState等,创建一个回调函数来接收来自外部的服务回调然后再发射的EndXXX和与AsyncResults处理国家再次在EndXXX,完全转移到通用的帮手。你写的代码量每一个操作,你想的是,我相信,现在相当合理。
让我们来看看如何在WcfAsyncHelper类看起来像:{C8的}  ;
正如你所看到的,已接管BeginAsync和EndAsync水暖工作处理与CustomState和CustomAsyncResult。我已经作出了类似的BeginSync和EndSync,您可以使用柜面您​​的BeginXXX呼叫需要异步调用而不返回立即响应。为例如,您可能有数据的缓存,你不想让外部服务再次呼吁得到的数据,而是立即返回。在这情况下,BeginSync和EndSync配对帮助。在WCF中使用异步Ajax代理异步模式
如果你想直接从外部域获取数据从JavaScript中,你需要一个AJAX代理。 javascript的击中了AJAX代理通过URL,它最终需要打代理然后发送从请求的URL的数据。这种方式可以克服在浏览器中的跨浏览器的XMLHTTP呼叫限制。这是需要在大多数Web 2.0的起始网页,如雅虎的iGoogle,我以前启动??{A2的}等。你可以看到AJAX从我的开源Web 2.0的起始页项目使用代理。
{七}
下面是一个WCF AJAX代理的代码,可以获取数据从外部URL,并返回它。它还支持高速缓存中的数据。因此,一旦它从外部域获取数据,然后缓存。代理是完全流。这意味着代理不先下载整个响应然后缓存它,然后返回它。这样的延误将几乎两倍从浏览器直接击中的外部URL,如果有可能的。我的代码这里将直接流从外部URL的响应,它会缓存动态响应。
一是在BeginGetUrl的 接收呼叫的功能,并打开一个HttpWebRequest请求的URL。它调用BeginGetResponseHttpWebRequest和回报。
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall, ConcurrencyMode=ConcurrencyMode.Multiple), AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Allowed), ServiceContract]

public partial class AsyncService

{

  [OperationContract(AsyncPattern=true)]

  //[WebGet(BodyStyle=WebMessageBodyStyle.Bare, UriTemplate="/Url?uri={url}&cacheDuration={cacheDuration}")] 

  [WebGet(BodyStyle=WebMessageBodyStyle.Bare)]

  public IAsyncResult BeginGetUrl(string url, int cacheDuration, AsyncCallback wcfCallback, object wcfState)

  {

      /// If the url already exists in cache then there's no need to fetch it from the source.

      /// We can just return the response immediately from cache

      if (IsInCache(url))

      {

        return WcfAsyncHelper.BeginSync<WebRequestState>(new WebRequestState

            {

                Url = url,

                CacheDuration = cacheDuration,

                ContentType = WebOperationContext.Current.IncomingRequest.ContentType,

            },

            wcfCallback, wcfState);

      }

      else

      {

        /// The content does not exist in cache and we need to get it from the

        /// original source                 

        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

        request.Method = "GET";

        //request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

        return WcfAsyncHelper.BeginAsync<WebRequestState>(

          new WebRequestState

          {

              Request = request,

              ContentType = WebOperationContext.Current.IncomingRequest.ContentType,

              Url = url,

              CacheDuration = cacheDuration,

          },

          wcfCallback, wcfState,

          (myState, externalServiceCallback, customState) => 

              myState.Request.BeginGetResponse(externalServiceCallback, customState));

      }

  } 

首先检查是否已经在请求的URL缓存。如果是的话,那么它会返回响应从缓存同步。这是其中的BeginSync和EndSync来得心应手。如果数据不在缓存中,然后它会使请求的URL的HTTP请求。
响应到达时,EndGetUrl被炒鱿鱼。{C10的}   ;
在这里检查,如果请求完成同步,因为该URL已经缓存。如果它完成同步,然后直接从缓存中返回响应。否则数据读取HttpWebResponse作为一个流,并返回数据。
我创建了一个StreamWrapper不仅返回从原来的流数据,也存储在一个MemoryStream缓冲区,使数据可以从原来的流读取数据时缓存。因此,它不会增加在第一次下载整个数据,然后缓存它的延迟,然后才将它发送回客户端。返回响应和缓存反应发生在一个单一的传球。{C11的}
时间来加载测试,并证明它的真正尺度。   ; 它不能扩展在所有NBSP!;
我做了一个负载测试,以比较改善通过同步实施的异步执行。同步实施简单,它只是使用的WebClient从给定的URL获得的数据。我犯了一个控制台应用程序,这将启动50个线程和打击使用25个线程的服务和使用其他25个线程,击出了一些ASPX页面,以确保服务调用是ASP.NET网站的功能,而怎么回事。另一台服务器上托管服务和故意响应速度很慢,到6秒,以完成该请求。负载测试使用三的HP ProLiant BL460c G1的刀片服务器,64位硬件,64位Windows 2008企业版。{S8的}

客户端代码将启动50个并行线程,然后打服务第一,精疲力尽长期运行的线程正在运行的服务。而服务请求执行的,它启动另一个线程设置为打一些ASPX页面。如果页面响应及时,那么我们有克服线程的问题,是真正的异步WCF服务。如果是这样不是,那么我们还没有解决的问题。 {C12的}  0;   ;
当我做这个同步服务,它表明预期的行为,ASP.NET页面需要更长的时间比服务调用执行ASP.NET请求,因为没有得到机会运行。
[SYNC]  15     116 End of ASP.NET Call. Duration: 10.5145348 

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  16     115 End of ASP.NET Call. Duration: 10.530135

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  17     114 End of ASP.NET Call. Duration: 10.5457352

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  12     142 End Service call. Duration: 142

[SYNC]  18     112 End of ASP.NET Call. Duration: 10.608136

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  19     113 End of ASP.NET Call. Duration: 10.608136

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  20     111 End of ASP.NET Call. Duration: 11.0293414

[SYNC] WARNING! ASP.NET requests running slower than service.

[SYNC]  21     109 End of ASP.NET Call. Duration: 11.0605418




当异步服务的测试运行,令人惊讶的是,它是同一件事情:
[ASYNC] 13      134 End of ASP.NET Call. Duration: 12.0745548

[ASYNC] WARNING! ASP.NET requests running slower than service.

[ASYNC] 14      135 End of ASP.NET Call. Duration: 12.090155

[ASYNC] WARNING! ASP.NET requests running slower than service.

[ASYNC] 15      136 End of ASP.NET Call. Duration: 12.1057552

[ASYNC] WARNING! ASP.NET requests running slower than service.

[ASYNC] 14      111 End Service call. Duration: 111 

[ASYNC] 15      110 End Service call. Duration: 110

[ASYNC] 16      137 End of ASP.NET Call. Duration: 12.5737612

[ASYNC] WARNING! ASP.NET requests running slower than service.

[ASYNC] 17      138 End of ASP.NET Call. Duration: 12.5893614

[ASYNC] WARNING! ASP.NET requests running slower than service.

[ASYNC] 18      139 End of ASP.NET Call. Duration: 12.6049616

的统计数据表明,我们有相同数量的减缓ASP.NET页面的执行和真的没有明显的区别之间的同步和异步版本的性能,也可扩展性。
<a name="OLE_LINK1">Regular service slow responses: 25</a> 

Async service slow responses: 25

Regular service average response time: 19.39416864

Async service average response time: 18.5408377

Async service is 4.39993564993564% faster.

Regular ASP.NET average response time: 10.363836868

Async ASP.NET average response time: 10.4503867776

Async ASP.NET is 0.828198146555863% slower.

Async 95%ile Service Response Time: 14.5705868

Async 95%ile ASP.NET Response Time: 12.90994551

Regular 95%ile Service Response Time: 15.54793933

Regular 95%ile ASP.NET Response Time: 13.06594751

95%ile ASP.NET Response time is better for Async by 1.19395856963763%

95%ile Service Response time is better for Async by 6.28605829528921%

确实没有显著的差异。轻微区别我们所看到的,很可能是由于网络打嗝,或只是一些线程延误。这是不是真正告诉我们,有显著改善。
然而,当我做这个异步ASMX服务,好老的ASP.NET 2.0 ASMX服务,结果如预期。毫无延迟无论ASP.NET请求执行的服务电话是多少进展。 "可扩展性的改进是显著。服务响应时间是33%的速度更快,最重要的是,在ASP.NET网页的响应,超过73%更好。
那么,这是否意味着所有的文章中,我们阅读有关WCF支持异步,使您的服务更长时间运行调用的可扩展性,都是骗人的吗?
我想我必须有书面的客户端的错误。所以,我惠普性能中心运行一些负载测试,看看如何同步和异步服务比较。我已经使用了50个Vuser打服务​​,另有50Vuser的同时打ASPX页面。 15后运行测试分钟,结果是一样的,同步和异步执行的WCF服务正显示出相同的结果。这意味着有没有改善异步执行。
{S9的}
图:异步服务负载测试结果
{S10的}
图:同步服务负载测试结果正如你可以看到,无论是表演或多或少相同。这意味着WCF中,现成的,不支持异步服务。
阅读一些MSDN博客文章中,我得到了确认。默认情况下,WCF具有同步HTTP处理程序持有ASP.NET线程,直到WCF请求完成。在事实上,它比好老的ASMX时IIS上承载WCF是更糟,因为它使用两个线程,每个请求。这里就是博客说:在。NET 3.0和3.5,有是一种特殊的行为,你会观察IIS承载WCF服务。每当一个请求到达时,系统将使用两个线程来处理要求: 一个线程是CLR ThreadPool线程这是从ASP.NET的工作线程。 另一个线程是一个I / O线程由WCF IOThreadScheduler的(实际ThreadPool.UnsafeQueueNativeOverlapped创建)进行管理。
博客文章,让你在那里你可以一劈实现一个自定义HttpModule你自己的,它取代了默认的同步的HttpHandler处理WCF请求一个异步的HttpHandler。如每个博客,它应该支持WCF请求的异步处理不持有ASP.NET线程。实施后,黑客和运行负荷试验,结果是一样的,黑客也不起作用。
{的S11}
图实施后,自定义负载测试报告的HttpModule
我已成功安装的HttpModule通过在web.config中配置的模块:{C17的}
,但仍然没有improvement.nbsp;
是,路的尽头?没有。NET 3.5 SP1的固定problem.nbsp;最终的解决方案,真正worksnbsp;
最后,我发现了MSDN职位。NET 3.5 SP1中证实,微软已经发布了异步HTTP处理程序执行。使用工具,可以安装在IIS的异步处理程序是默认和只WCF异步服务真正成为异步。
除了现有的同步的WCF HTTP模块/处理器类型,WCF引入了异步版本。现在有共有四种类型的HTTP模块实现:{C18的}
下面的命令将安装异步HTTP模块和将油门设置为200。这意味着不超过200请求将排队。这将确保异步请求没有得到排队无限期服务器遭受内存不可用。{C19的}
一旦安装工具,我运行我的客户端来测试的改善,我可以看到响应时间显着改善。
运行该工具后
之前运行该工具 0;
定期服务缓慢的回应:0 60;
定期服务反应缓慢:25
异步服务缓慢的回应:0 &# 160;
异步服务缓慢的反应:25 & #160;
定期服务的平均响应时间:16.46133104
定期服务的平均响应时间:19.39416864 0;
异步服务的平均响应时间:12.45831972
异步服务的平均响应时间:18.5408377
常规ASP.NET的平均响应时间:2.1384130152
常规ASP.NET的平均响应时间:10.363836868  0;
异步ASP.NET的平均响应时间:2.214292388  0;
异步ASP.NET的平均响应时间:10.4503867776
异步95%ILE服务响应时间:7.1448916
异步95%ILE服务响应时间:14.5705868
异步95%ILE ASP.NET响应时间:3.62782651
异步95%ILE ASP.NET响应时间:12.90994551 & #160;
例行95%的ILE服务响应时间:15.32017641
例行95%的ILE服务响应时间:15.54793933
例行95%ILE ASP.NET响应时间:3.30022231
例行95%ILE ASP.NET响应时间:13.06594751
运行该工具后,WCF服务的响应2X更好的ASP.NET页面响应4X更好。
负载测试报告也印证了显著改进:
{的S12}
图:交易提高2倍后每秒正在运行的WCF工具

图:服务的平均响应时间ASP.NET页面是WCF工具运行后的近一半。
所以,这证明,WCF支持异步服务预期。NET 3.5 SP1中已取得显着改善,在支持真正异步服务。等待它显示出相同的改善同步和异步的!
你是正确的,它并没有使刚刚异步更好,但也取得了同步更好。都显示出相同的改进。原因是工具线程数最多的肉牛提供服务的请求。它不使异步更好的服务。你一定要使用的工具,来加强您的服务器的能力,如果你发现服务器没有真正给予其最好的。但它并没有真正解决问题,异步服务不给你比同步服务更好的效果显著。
所以,我有一些电子邮件交流与达斯汀从微软WCF团队。下面是他解释说:
喜奥马尔
我想这可能有助于说明什么发生你test.nbsp;
{S14系列}
首先,在文龙的博客文章,他的谈话为什么有两个线程,每个请求:一个工作线程和一个IO线程。测试说明了这一点,它在上面的配置文件中可见。
是突出显示的线程(4364)我特别显示。这是一个工人线程池线程。它正在等待HostedHttpRequestAsyncResult.ExecuteSynchronous作为强调在堆栈追查。你也可以告诉大家,这是由三个工人线程池线程休眠1秒每发生只要该线程是可用。什么你还可以看到的是这个工作线程是一个线程畅通下方(3852)。
关于3852线程有趣的是,它不会在同一时间为4364开始。这样做的原因是因为你使用WCF中的异步模式。然而,一旦后面的终端服务(回声)开始返回数据,IO线程抓起,从IO线程池用来读回来的数据。由于你的后端流和许多在那里停下来返回数据,它需要很长的时间来得到整个事情。因此,一个IO线程被阻塞。
如果你要使用同步模式WCF中,你会发现,IO线程阻塞的整个时间工作者线程被阻塞。但它结束了,没有多大的差别因为事实上,一个IO线程将被长期封锁反正时间在同步或异步的情况下。
使用异步模式时,工作线程池将成为一个瓶颈。如果你只是增加的minWorkerThreads,的processModel,所有的{A5的}请求将通过(工作线程)去之前,WCF异步请求,这是我假设你正在试图做你的测试代码。
现在,让我们说,你切换到。NET 4.0。现在你没有使用两个线程,每个请求的相同问题。下面是一个配置文件只是在中间层上使用NET 4.0:

7 {A5的}请求都发生在同一时间(显示的公告蓝色睡1秒)。有三个1秒睡只是有点迟,这是发生,因为没有足够的工人可用线程。你还会发现独特的紫色IO线程颜色,这是表示等待IO。因为上回的Echo服务WCF请求结束流,并已在它暂停,阻塞一个线程同时接收数据。我运行的默认设置,所以只有2核心默认分钟IO线程数是2(其中之​​一是由定时器线程)。其余的服务电话,有新的IO线程等待创建。再次,这是WCF异步的情况下。如果你是切换到同步的情况下,它不会有太大的不同,因为它会阻止一个IO线程,但只为更短的时间内。
我希望这有助于解释你看到什么您的测试。 Dustinnbsp";
,但令我困惑的是,如果WCF 3.5支持异步服务和异步HTTP模块安装,为什么我们有相同的可扩展性问题?是什么让WCF的4.0执行这么多的WCF更好3.5?

因此,我尝试了各种组合的minWorkerThreads,maxWorkerThreadsminIOThreads,maxIOThreads,minLocalRequestFreeThreads,设置,看看是否异步HTTP模块是在WCF 3.5 SP1真的让任何差或没有。这里是我的发现:
主题
maxWorkerThreads" & #160;
maxIOThreads"
minWorkerThreads"
minIOThreads"  0;
minFreeThreads"
minLocalRequestFreeThreads"
ASP.NET更好
更好的服务 100  60; 200 200 &# 160; 40 30 20 &# 160; 20 -1.49% & #160;66% 100   ;100 100 40 & #160; 30 352 304 60; 0% 66% &# 160; 100
汽车 &# 160;
汽车
汽车
汽车
汽车   ;
汽车 0% 66% 100 100   ; 100 50 50 352 304 &# 160; -7% 66%   ; 300
汽车   ;
汽车
汽车
汽车
汽车
汽车 1.26% 37% 300 200 &# 160; 200 40 30 20 20 0% 38% &# 160; 300 200 200 40 30  0;352 304 0%   ; 39% 300  60; 100 100 40  ; 30 352 304 0% 39%   ; 300 100 100 40   ;30 20 20   ; 这没有什么区别。
所以到达斯汀:
喜奥马尔
所以我通过你的榜样,更彻底地去,我相信我已经想通了什么造成问题。下面是一个示例输出从我做了一个测试运行您的样品与一些修改:{C20的}
这是使用100个线程的运行。附完整的日志。有一些事情,我花了注意,防止你看到一个差异之间的异步和同步:
最重要的一条是后端服务Echo.ashx。 ASP.NET即使是让所有的请求通过,因为这是做一个视频下载数(),它被阻塞工作线程。工作线程在每秒2坡道,如果你扔50在这一次所有的请求,你将不得不等待。是否使用异步或不能在中间层不是要做出difference.You之间有一个10秒的睡眠异步和同步。这实际上有利于同步的倾斜的结果。线程不会死的建立是为了处理异步工作由于不活动至少15秒。我这睡眠增加至30秒,使事情fair.Your Echo.ashx开始返回数据后1秒,然后需要1.5秒,完成返回数据。此块在中间层的IO线程,这导致了两个问题:如果 minIoThread计数不够高,那么你仍然会等待让你有更多的线程来处理,同时每秒门2work.nbsp;由于提到的bug {A7的}minIoThread设置可能没有超过time.nbsp效果;

为了让你的测试工作正常,我做了一个数量的变化:
增加minWorkerThreads上使后端Echo.ashx服务,它可以处理所有的交通simultaneously.Increased的minWorkerThreads上 中间层服务,因此它可以处理所有的ASP.NET请求从博客simultaneously.Used解决办法发表上述使用的SynchronizationContext在移动工作在中间层AsyncService IO线程池的工作线程池。如果一切按计划进行,所有的ASP.NET请求完成前的Echo.ashx开始返回数据,所以应该大量工作线程available.nbsp
我 没有到改变minFreeThreads或minLocalRequestFreeThreads。
请让我知道如果有什么事情,目前还不清楚。达斯汀
因此,我们有一个WCF的IO线程池管理的无证行为。问题是,线程启动时,有一个缓慢的启动时间线程。线程正在逐渐增加,即使你突然队列100工程在ThreadPool。你可以看到从性能计数器。如果你添加w3wp进程的线程,你会看到有一个缓慢的rampup:
{S16号}
WCF使用。NET CLR的I / O完成端口的线程池执行您的WCF服务的代码。遇到问题时,净CLR IO完成端口的线程池进入状态,它不能创建线程不够快,立即请求处理突发。响应时间的增加,意外地创建新的线程都在1%的速度500ms的。
最明显的事情然后将增加的IO线程的最小数目。你可以这样做在两个方面:的使用ThreadPool.SetMinThreads或使用LT; processModelgt;标签在machine.config。这里是如何做到后者:{C21的}
务必关闭自动配置的设置或其他选项将被忽略。如果我们再次运行这个测试,我们得到一个更好的结果。比较以前的快照一的permon的:

但是,如果你保持一段时间,负载测试运行,你会看到它可以追溯到旧的行为:
{S18纯}
所以,现在真的是没有办法来解决这个问题的调整配置设置。它证实了我已经做了早些时候与研究线程池设置的各种组合,看到没有区别在于制成。
,达斯汀建议的习俗Juval洛伊的SynchronizationContext实施。使用可以移动从WCF的IO线程池的CLR线程池的请求。 CLR的工人线程池不会有问题。使WCF执行请求的解决方案使用CLR线程池被记录在这里:{A8的}
conclusionnbsp;的WCF本身支持异步模式无处不在,它可以用来建立更快和更具可扩展性比的ASMX Web服务。这是WCF的默认安装配置不支持异步模式正确。所以,你需要调整运行该工具,IIS的配置和使用IO ThreadPool的错误修复WCF的优势在其最好的享受。 {A9的}:奥马尔・Zabir:freemanm:优秀的,我喜欢你的所有文章

回答

评论会员: 时间:2