【问题标题】:What is the overhead in using a .NET Service Reference to call a web service?使用 .NET 服务引用调用 Web 服务的开销是多少?
【发布时间】:2013-06-29 21:43:15
【问题描述】:

我正在使用第三方的网络服务。我正在测量调用 Web 方法和定时网络流量所需的时间。我发现通话花费的时间比网络流量长得多。

我运行应用程序并使用 fiddler 来观察流量,打开 HTTP CONNECT 隧道需要 46 毫秒,发送数据需要 951 毫秒。我预计这个总数约为 1000 毫秒,但它的输出时间为 1504 毫秒。 500 毫秒可能看起来不多,但这是在测试服务器上完成的,我们经常看到实时服务器的响应时间为 6 秒,而网络调用则需要 1 秒。

这是我用来测量网络方法调用时间的代码

  Dim service As New SupplementaryEnquiryV1PortTypeClient()

    Dim _stopWatch As New Stopwatch()

    _stopWatch.Start()

    response = service.Enquiry(request)

    _stopWatch.Stop()

客户端用VB .NET编写,框架版本4.5

客户端是通过在visual studio中添加服务引用生成的,我也尝试过使用svcutil.exe生成服务引用。

我相信 Web 服务是用 Java 编写的,但我无法访问代码。该服务返回有关单个车辆的数据,我假设这些数据是从数据库中提取的。

我尝试使用不使用 SSL 的服务端点,但没有任何区别。

我尝试将 System.ServiceModel.ClientBase(Of T) 上的 CacheSetting 属性设置为 AlwaysOff 和 A​​lwaysOn,但都没有任何区别。我还尝试将项目的“生成序列化程序集”设置为 On。

我已使用 traceroute 检查任何与网络相关的问题。

来自提琴手:

CONNECT uat-wss.xxx.co.uk:443 HTTP/1.1

ClientConnected: 15:23:20.011
ClientBeginRequest: 15:23:20.027
GotRequestHeaders: 15:23:20.027
ClientDoneRequest: 15:23:20.027
Determine Gateway: 0ms
DNS Lookup: 29ms
TCP/IP Connect: 18ms
HTTPS Handshake: 20ms
ServerConnected: 15:23:20.074
FiddlerBeginRequest: 15:23:20.074
ServerGotRequest: 15:23:20.074
ServerBeginResponse: 00:00:00.000
GotResponseHeaders: 00:00:00.000
ServerDoneResponse: 00:00:00.000
ClientBeginResponse: 15:23:20.074
ClientDoneResponse: 15:23:20.074

Overall Elapsed: 0:00:00.046

POST /TradeSoap/services/SupplementaryEnquiryV1/ HTTP/1.1

ClientConnected: 15:23:20.011
ClientBeginRequest: 15:23:20.105
GotRequestHeaders: 15:23:20.105
ClientDoneRequest: 15:23:20.464
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 0ms
HTTPS Handshake: 0ms
ServerConnected: 15:23:20.074
FiddlerBeginRequest: 15:23:20.464
ServerGotRequest: 15:23:20.464
ServerBeginResponse: 15:23:20.479
GotResponseHeaders: 15:23:20.994
ServerDoneResponse: 15:23:21.041
ClientBeginResponse: 15:23:21.041
ClientDoneResponse: 15:23:21.057

Overall Elapsed: 0:00:00.951

编辑

按照 usr 的建议,我已将代码放入分析器。我在 2012 年使用过内置的(见下文)。看起来 Microsoft.Xml.Serialization.ArrayOfObjectsSerializer1.Deserialize 占用了大量时间。什么可能导致这需要几秒钟?

【问题讨论】:

  • 网络服务有什么作用?是否可能在服务器上处理数据和/或访问需要时间的数据库?另外,从开始到响应确认的提琴手跟踪样本是什么?握手结束 46 毫秒,最后发送数据包的 951 确认,???第一个响应包,???最后一个响应包的ack? (发送和响应数据有多大?)
  • 我已更新问题以包含提琴手响应。我对 Web 服务在做什么不太感兴趣,因为我无法控制它。我想知道为什么创建 SOAP 请求和接收 SOAP 响应需要这么长时间。
  • 打开探查器,或在满载情况下暂停调试器 10 次。在代码花费时间的地方回答问题非常容易。
  • 试试探查器?这应该告诉您应用程序将时间花在哪里。否则,我只能告诉您时间似乎过多,但我不会客观地知道,因为我使用 SSD 在本地工作,而不是在 VM 片上的开发服务器上工作。
  • 啊,所以客户端发送时间是1/2秒,服务器认为时间是1/2秒。您只是想找到似乎超出此周期且仅与客户相关的额外时间。除了这个一个连接和一个帖子之外,提琴手还有什么其他事情吗?大约在同一时间发生的任何事情都可能相关。 (我不认为请求/响应如此简单,您可以编写一个 TCP 测试应用程序来在没有 SSL 的情况下运行它?这可以确认这是一个客户端问题)

标签: .net web-services service-reference


【解决方案1】:

您可能正在见证 Nagle 算法的效果,试试吧:

this.webRequest.UseNagleAlgorithm.ServicePoint = false;

此外,Expect100Continue“握手”与肥皂服务调用性能有关:

this.webRequest.Expect100Continue.ServicePoint = false;

Nagle 将在短时间内暂停发送网络数据包,以尝试发送更少但更大的数据包。在通过公共互联网进行通信时,使用它可能是一个礼仪问题。做你自己的研究。

Expect100Continue 将阻止在初始 HTTP PUT/POST 上发送 SOAP 请求 XML,服务器将发送 OK/CONTINUE,然后客户端将发送 SOAP 请求 XML。这种额外的握手(两次完整的往返一次)也会引入延迟。

【讨论】:

  • 我试过 ServicePointManager.UseNagleAlgorithm = false 但这似乎并没有改善时代。 ServicePointManager.Expect100Continue = false 似乎确实提供了轻微的改进,因此我将其添加到代码中。但是我更感兴趣的是没有用于网络访问的时间。我认为准备发送请求或阅读响应似乎花费了很多时间,但我不确定为什么要花这么长时间。
  • 不幸的是,.Net 中所有内置的序列化/反序列化都非常缓慢,并且根据您的分析器结果,我认为这就是您的问题所在。您的“请求”参数是什么类型的对象?我怀疑如果您使用 XmlDocument 或 XDocument,那么您将避开缓慢的对象序列化 - 值得一试。我们在这里编写了自己的代码来进行 SOAP 调用,部分原因就是这个问题。
  • 请求是一个相当简单的对象,只提供身份验证信息、车辆的牌照和所需的响应类型。响应要复杂得多,包含许多非常详细的车辆信息。我确实觉得我最终会为这个肥皂电话编写自己的课程。
【解决方案2】:

您可能会因为您的客户端(VB.Net 应用程序)没有打开超过两个与服务的并发连接而受到影响。

如果您对page.aspx 有 10 个并发请求,并且此页面对每个请求执行一次服务调用,那么您基本上需要 10 个并发 Web 服务调用。

但默认情况下,Asp.Net 将对同一目标的并发 http 调用数限制为两个。所以在这个假设的情况下,10 个页面请求中有两个会主动调用服务,另外 8 个会等待轮到它们。当前两个完成后,两个新的将调用该服务,依此类推。

您可以使用web.config 设置来控制它:

<system.net>
    <connectionManagement>
        <add address="http://address.of.service/here" maxconnection="10"/>
    </connectionManagement>
</system.net>

另请参阅 here、here 或仅在 Google 上查看 system.net connectionmanagement maxconnection 并查看结果。

请注意,尽管显着增加此数字,您将对第三方服务施加更大的压力...

另请注意,更改 maxconnection 不会提高任何单个服务调用的性能,但它可能会提高生产环境中的性能,因为到VB.Net 网站。

【讨论】:

  • 现在我再次阅读了这个问题,我注意到没有任何地方提到过 Asp.Net。 default max 2 connections 也会影响 Windows 应用程序,但 heavier traffic in prod due to incoming requests 当然不太可能是这种情况的原因。无论如何,我都会保留答案,以防万一它有用...
  • 我读到了msdn.microsoft.com/en-us/library/ff647813.aspx,它建议将 maxconnection 设置为 12 * # of CPUs。所以我在 Web 服务器上将此值设置为 24。我会继续观察,看看这是否改善了时代。
  • 我今天检查了生产环境,不幸的是这并没有解决响应缓慢的问题。将 maxconnection 设置得太低可能会导致速度变慢,因此我将其设置为 24。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多