【问题标题】:Stream writeheaders take too much time WCF流 writeheaders 花费太多时间 WCF
【发布时间】:2013-04-16 10:39:31
【问题描述】:

NewRelic stream & writeHeaders 提出了类似的问题

我在 New Relic 上分析我的 WCF 服务。有一个WCF 服务调用另一个WCF 服务。 现在我想在调用另一个 WCF 服务时,当它创建请求时,内部进程在某处将标​​头写入请求流,这有时很慢。 我在 New Relic 中找到的痕迹告诉我,对于我的一个 WCF 服务的特定方法,它调用我的另一个 WCF 服务的方法,大约需要 50-60 秒,其中 95-100 % 的时间被消耗System.Net.ConnectStream.WriteHeaders。

Stream[url of WCF service/soap]: WriteHeaders -> 99.78 % time (approx 49 seconds).

我没有得到它是什么以及如何减少这个时间?

我已经搜索过,但没有找到 ConnectStream 实际做什么或有关它的一些细节,因此我可以找到任何方法来减少它所花费的时间。

请告诉我你的建议。

【问题讨论】:

  • 嗨@Deeps,你有这个问题吗?我们也面临着完全相同的问题。如果是的话,你能分享一下吗? TIA
  • 嗨,texens,抱歉回复晚了。不,直到现在我还没有任何解决方案。

标签: performance wcf stream httpwebrequest newrelic


【解决方案1】:

听起来您正在从客户端流式传输一个大文件,在一个 WCF Web 服务中捕获它,然后将数据重新写入新的 HttpWebRequest,然后将其发送到另一台主机。我想我很想尝试将数据从客户端缓冲到您的 Web 服务而不是流式传输。

去年我一直在从事一个听起来与您正在做的事情相似的项目。流式传输和缓冲之间的区别是:

流式读取(从源)然后将数据写入(到目标)在一个您没有太多控制权的交互过程中。如果源文件很大(比如 gig 或更多),WCF 请求/响应将在请求完成之前在客户端和主机之间来回迭代十几次或更多次。

另一方面,缓冲会在填充请求并将其发送到主机之前累积目标文件的全部内容,从而加快处理速度。而且由于缓冲带来的性能损失(在内存中累积字节所需的时间)是放在客户端上的,因此通常不是问题。

因此,当缓冲来自客户端的数据时,您的主机将收到一个带有完整字节数组(比方说)的 Http 请求,该请求已准备好重新打包到您传递到第二个目标 WCF 主机的请求中。在这一点上,您可以再次在缓冲和流式传输之间进行选择。在主机上,性能很重要,将请求流式传输到第二台主机将提高您的可伸缩性,但(再次)可能会损害您的性能速度。

在客户端:

    With binding
      .TransferMode =TransferMode.Buffered 'instead of Transfermode.Streamed                                                              
      .MessageEncoding = WSMessageEncoding.Text
      .TextEncoding = System.Text.Encoding.UTF8
      .MaxReceivedMessageSize = Integer.MaxValue
      .ReaderQuotas.MaxArrayLength = Integer.MaxValue
      .ReaderQuotas.MaxBytesPerRead = Integer.MaxValue
      .ReaderQuotas.MaxDepth = Integer.MaxValue
      .ReaderQuotas.MaxNameTableCharCount = Integer.MaxValue
      .ReaderQuotas.MaxStringContentLength = Integer.MaxValue
      .MaxBufferSize = Integer.MaxValue
      .MaxBufferPoolSize = Integer.MaxValue

在主机端:

With binding
      .TransferMode = TransferMode.Buffered
      .MaxReceivedMessageSize = Integer.MaxValue

【讨论】:

  • 嗨,Brian,我没有流式传输任何大文件或其他东西。它只是我要求的 WCF 服务。我在我的项目中添加了 WCF 服务的服务引用,该项目也是 WCF 服务。现在,我的服务中有一个方法 GetMerchantData(string param1),它从我的数据库中获取一些值,然后调用添加的服务引用的方法:GetMerchantStoreData(string param1, string param2, string param3)。请求如下所示:
  • MyServiceRefClient 客户端 = new MyServiceRefClient(); var 结果 = client.GetMerchantStoreData(param1, param2, param3);然后我从我的服务中返回这个结果。此结果对象包含 12 个属性。我不认为它是大数据或任何流媒体。我认为这与在向 ssl 托管的 wcf 服务发出请求时编写一些默认标头有关。但我不知道我能做些什么来减少这个时间。因为我没有在任何地方的代码中写过这一行 Stream[url of WCF service/soap]: WriteHeaders 。谢谢。
  • 我明白了。抱歉,我无法提供更多帮助。
【解决方案2】:

当您调用的服务停止或被太多并发连接淹没时,我之前也看到过同样的情况。如果问题是前者,分析您的 WCF 服务可能有助于确定根本原因 - 可能由于数据库访问或其他一些 I/O 绑定进程而导致响应缓慢。如果问题是后者,您可能可以通过调整服务性能来解决 (http://msdn.microsoft.com/en-us/library/ee377061(v=bts.10).aspx)

这也可以表现为 New Relic 中 ASP.NET 应用程序的“BeginRequest”。 BeginRequest 或 WriteHeaders 很少表示问题确实出在发送数据本身,尽管如果您的有效负载很大,但在传输数据很小的常规调用中,会出现连接时间慢或响应慢的问题在这两个方面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多