ASMX Web服务缓慢的第一个请求
我有一堆运行在一个IIS应用程序中的.NET Web服务。 这些Web服务被另一个IIS应用程序(前端)使用。 第一个电话很慢,约5到10秒。 之后,这只是毫秒。 第一个电话被认为是一个性能问题。
我们尝试了一个调用所有这些Web服务的应用程序,但是这显然不能解决任何问题。 所以这不是默认的应用程序回收问题。 我已经创build了一个应用程序,多次初始化服务,并测量创build一个实例所需的时间。 在运行此应用程序之前,我确保我的web服务应用程序已启动/回收,然后运行该应用程序。 第一次初始化需要2到4秒,其他时间只有毫秒。
另一个想法是,我们在Frontend应用程序中创build一个页面,该页面启动所有Web服务,并且在任何用户访问之前调用此页面。我不认为这是一个优雅的解决scheme,我还可以尝试什么?
客户端首次调用webservice时遇到的延迟是由于缺省情况下需要编译用于webservice的XmlSerializers dll。 这导致了最初的呼叫2-4秒。 当然,这是在web服务应用程序已经运行的情况下,如果它不是你会有一个回收。 在这种情况下,其他答案可能会有帮助。
为了加速初始调用,您可以在编译时创buildXmlSerializers DLL。 您可以通过将项目生成“生成序列化程序集”设置为打开。 这会生成一个包含webservice信息的MyApplication.XmlSerializers.dll。 现在最初的调用降到了300毫秒,大概是dll的加载。 那里的所有电话都需要0毫秒。
在Visual Studio中,右键单击您的项目,然后select“属性”。 转到“构build”选项卡。 在“输出”部分有一个选项“生成序列化程序集”。 如果将该值更改为“On”,则序列化程序集将在编译期间生成。
第一次调用web服务时,或第一次长时间延迟后,web服务需要启动。 这是你看到延迟的地方。 之后,它已经开始,并会很快响应通话。 这是标准的Web服务行为。
您可以将IISconfiguration为keepalive = true – 这可能会提高性能。
更多信息请求。
可能是序列化程序集正在运行时创build。 您可以使用项目属性窗口的“生成”窗格底部的下拉列表来更改序列化程序集的设置。
这可能是因为你已经编写了你的Web服务来在应用程序启动时执行很多操作,这将在第一次调用服务的方法时发生。
这可能是操作非常缓慢,但是你正在caching响应,这使得后续调用更快。
我最近发现,在我们的ASMX文件中,我们只提到类名。 我们在每个ASMX文件的不同程序集中获得了服务实现。 这会导致.NET框架扫描整个bin文件夹,寻找包含实现的程序集。 随着您的Web服务应用程序的增长,这将消耗更多的时间。 这不仅可以通过在ASMX定义中包含类名来解决,而且可以通过组合名来解决。
我们的ASMX看起来像这样:
<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice” %>
如果将其更改为包含包含实现的程序集,它将如下所示。 这节省了我们约10%的web服务应用程序的初始负载。
<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice, MyWebservice.Implementation.Assembly” %>
这是典型的,因为ASP.NET应用程序在第一次请求时编译并将bin \目录加载到内存中。
事情要做:
删除bin目录中的所有不必要的dll。 (我见过人们运送nunit.dll)
预编译您的ASP.NET应用程序,以便IIS不需要。 请参阅“ VS 2008 Web部署项目支持 ”
不知道这是否会解决WS在“第一次”慢旋转起来,因为我认为有负载的编译和.net DLL的加载,但你几乎可以通过确保应用程序池WS正在configuration正确。
默认情况下,IIS6在空闲时重新启动,经过几分钟或“回收”事件,每次都有效地重新启动WS。 如果你的服务是稳定的,那么这些都是不需要的。
确保WS拥有自己的专用应用程序池(不共享不适当的池)也是一个强有力的build议。
经过几个小时的疯狂testing,我已经能够减lessnetworking服务的首次执行时间,从两个主机在相同的IP类(低于300毫秒)最低。
我首先在第一次Web服务调用时经历了2-3秒的初始延迟,而后来的任何来自同一进程的调用都非常快。
理解延迟在我的情况的关键是如何客户端处理WEB代理!
这是我在app.config文件中的新绑定:
<basicHttpBinding> <binding name="CreateContextSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="16777216" maxBufferPoolSize="524288" maxReceivedMessageSize="16777216" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="false"> <readerQuotas maxDepth="32" maxStringContentLength="1048576" maxArrayLength="16384" maxBytesPerRead="65536" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding>
我认为第一个webcall执行速度要慢得多,因为传输通道需要在初始化时发现代理configuration,以便透明地连接到互联网。 这通常不需要进入Intranet环境,因此我更改了这些绑定设置以避免使用默认代理(从资源pipe理器设置中自动发现):
bypassProxyOnLocal = “假”
useDefaultWebProxy = “假”
首次通话连接时间现在减less了很多。 希望这可以帮助。