.net ASMX Web 服务较慢的第一个请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/784918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:34:52  来源:igfitidea点击:

ASMX Web Service slow first request

.netweb-servicesasmx

提问by Remco Eissing

I have a bunch of .NET Webservices running in one IIS Application. These webservices are consumed by another IIS Application (frontend). The first call is pretty slow, about 5 to 10 seconds. After that it's just milliseconds. The first call is considered a performance problem.

我在一个 IIS 应用程序中运行了一堆 .NET Web 服务。这些 Web 服务由另一个 IIS 应用程序(前端)使用。第一次调用很慢,大约 5 到 10 秒。之后只是几毫秒。第一次调用被认为是性能问题。

We've tried an application that calls all these webservices but this obviously doesn't solve anything. So it's not the default Application Recycle that is the problem. I've created an application that just initializes the service several times and measures the time it takes to create one instance. Before running this application I ensure that my webservice application is started / recycled, then I run the application. The first initialization takes between 2 to 4 seconds, all others is just milliseconds.

我们已经尝试了一个调用所有这些网络服务的应用程序,但这显然没有解决任何问题。因此,问题不是默认的应用程序回收。我创建了一个应用程序,它只是多次初始化服务并测量创建一个实例所需的时间。在运行这个应用程序之前,我确保我的 webservice 应用程序已启动/回收,然后我运行该应用程序。第一次初始化需要 2 到 4 秒,所有其他初始化只需几毫秒。

Another thought is that we create a page in the Frontend application that initiates all the webservices and that we call this page before any users are in. I don't consider this as an elegant solution, what else could I try?

另一个想法是,我们在 Frontend 应用程序中创建一个页面来启动所有 Web 服务,并在任何用户进入之前调用此页面。我不认为这是一个优雅的解决方案,我还能尝试什么?

回答by Remco Eissing

The delay that is experienced when a client is calling a webservice for the first time is caused by the fact that by default a XmlSerializers dll for the webservice needs to be compiled. This is causing the 2-4 seconds for the initial call. Of course this is the case when the webservice application is already running, if it's not you would have a recycle. In which case the other answers could help.

客户端第一次调用 Web 服务时遇到的延迟是由于默认情况下需要编译 Web 服务的 XmlSerializers dll 造成的。这导致初始呼叫的 2-4 秒。当然,当 webservice 应用程序已经在运行时就是这种情况,如果不是,你会有一个回收。在这种情况下,其他答案可能会有所帮助。

To speed up the initial call you can create the XmlSerializers dll at compile time. You can do this by setting your project build 'Generate serialization assembly' to on. This generates an MyApplication.XmlSerializers.dll containing the webservice information. Now the initial call dropped to 300 ms, presumably the loading of the dll. All calls there after take 0 ms.

为了加速初始调用,您可以在编译时创建 XmlSerializers dll。您可以通过将项目构建“生成序列化程序集”设置为开启来实现此目的。这会生成一个包含 Web 服务信息的 MyApplication.XmlSerializers.dll。现在初始调用下降到 300 毫秒,大概是 dll 的加载。0 毫秒后,那里的所有呼叫都在那里。

In Visual Studio right click on your project and choose 'Properties'. Go to the 'Build' Tab. There you have an option 'Generate Serialization assembly' in the 'Output' section. If you change the value to 'On' the serialization assembly will be generated during compile time.

在 Visual Studio 中右键单击您的项目并选择“属性”。转到“构建”选项卡。在“输出”部分中有一个选项“生成序列化程序集”。如果将该值更改为“On”,则将在编译期间生成序列化程序集。

回答by Fenton

The first time you call the webservice, or the first time after a long delay, the web service needs to start up. This is where you're seeing the delay. After that, it's already started and will respond really quickly to calls. This is standard web service behaviour.

第一次调用webservice,或者长时间延迟后的第一次,需要启动web service。这就是您看到延迟的地方。在那之后,它已经开始并且会非常快速地响应呼叫。这是标准的 Web 服务行为。

You could configure IIS to have keepalive = true - which may improve the performance.

您可以将 IIS 配置为 keepalive = true - 这可能会提高性能。

More information as requested.

根据要求提供更多信息。

It could be that the serialization assemblies are being created at runtime. You can change the settings of the serialization assembly using the dropdown at the bottom of the Build pane of the properties window for the project.

可能是在运行时创建了序列化程序集。您可以使用项目属性窗口的 Build 窗格底部的下拉列表更改序列化程序集的设置。

It could be that you have written your web service to perform a lot of operations on application start, which would happen the first time a method on the service is called.

可能是您编写了 Web 服务以在应用程序启动时执行大量操作,这会在第一次调用服务上的方法时发生。

It might be that the operation is very slow, but you are then caching the response, which makes subsequent calls faster.

可能是操作非常慢,但是您正在缓存响应,这使得后续调用更快。

回答by Remco Eissing

I recently discovered that in our ASMX-files we only referred to the class name. We got the service implementation in a different assembly for each ASMX-file. This causes .NET framework to scan through the entire bin-folder looking for the assembly containing the implementation. As your webservice application grows this will consume more time. This can be solved by not only including the class name in your ASMX definition but also the assembly name.

我最近发现在我们的 ASMX 文件中我们只引用了类名。我们为每个 ASMX 文件在不同的程序集中获得了服务实现。这会导致 .NET 框架扫描整个 bin 文件夹以查找包含实现的程序集。随着您的 Web 服务应用程序的增长,这将消耗更多时间。这可以通过不仅在 ASMX 定义中包含类名而且在程序集名称中包含来解决。

Our ASMX looked like this:

我们的 ASMX 看起来像这样:

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice” %>

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice” %>

If you change it to include the assembly that contains the implementation it would look like this. This saved us around 10% of our initial load of the webservice application.

如果您将其更改为包含包含实现的程序集,它将如下所示。这为我们节省了大约 10% 的 Web 服务应用程序初始负载。

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice, MyWebservice.Implementation.Assembly” %>

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice, MyWebservice.Implementation.Assembly” %>

回答by Chad Grant

That is typical, since ASP.NET apps compile and load the bin\ directory into memory at first request.

这是典型的,因为 ASP.NET 应用程序会在第一次请求时编译并将 bin\ 目录加载到内存中。

Things to do first:

首先要做的事情:

Remove all unnecessary dll's in your bin directory. (I've seen people ship nunit.dll)

删除 bin 目录中所有不必要的 dll。(我见过有人发布 nunit.dll)

Precompile your ASP.NET app so that IIS does not need to. See "VS 2008 Web Deployment Project Support Released"

预编译您的 ASP.NET 应用程序,以便 IIS 不需要。参见“ VS 2008 Web 部署项目支持发布

回答by Guy

Not sure if this will solve slow spin up of the WS on the "very first time", as I assume there is a load of compiling and .net DLL's being loaded, but you can almost eliminate any future cold starts by ensuring the application pool the WS is in is configured correctly.

不确定这是否会在“第一次”解决 WS 缓慢启动的问题,因为我假设有大量编译和 .net DLL 正在加载,但是您几乎可以通过确保应用程序池来消除任何未来的冷启动WS 中的配置正确。

By default, IIS6 has "respawn" on idle, after a number of minutes or "recycle" events that effectively restart the WS each time. If your happy the service is stable then these are not needed.

默认情况下,IIS6 在空闲时“重生”,经过几分钟或每次有效重新启动 WS 的“回收”事件。如果您对服务稳定感到满意,则不需要这些。

Ensuring that the WS has it's own dedicated application pool (is not sharing an inappropriate pool) is also a strong recommendation.

确保 WS 拥有自己的专用应用程序池(不共享不适当的池)也是一个强烈建议。

回答by Paolo Marani

After several hour of insane testing, i has been able to reduce the webservice first-run execution time to bare minimum from two host in the same IP class (below 300msec)....

经过几个小时的疯狂测试,我已经能够将同一 IP 类中的两台主机的 webservice 首次运行执行时间减少到最低限度(低于 300 毫秒)。...

I experienced at first an initial delay of 2-3 sec at first webservice call, than any subsequent call from the same process to be very fast.

我在第一次 webservice 调用时经历了 2-3 秒的初始延迟,比来自同一进程的任何后续调用都非常快。

The key for understanding the delay in my case was how client handles WEB PROXY !!

在我的案例中理解延迟的关键是客户端如何处理 WEB PROXY !!

This is my new binding in app.config file:

这是我在 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>

The first webcall execution i suppose to be much slower because transport channel need to discover proxy configuration on initialization, in order to transparently connect to internet. This is usually not needed into intranet environment, thus i have changed these binding settings to avoid use the default proxy (automatically discovered from explorer settings):

我认为第一个 webcall 执行要慢得多,因为传输通道需要在初始化时发现代理配置,以便透明地连接到互联网。这在 Intranet 环境中通常不需要,因此我更改了这些绑定设置以避免使用默认代理(从资源管理器设置中自动发现):

bypassProxyOnLocal="false"

绕过代理OnLocal =“假”

useDefaultWebProxy="false"

useDefaultWebProxy="false"

The first-call connection time is now reduced by a large amount. Hope this helps.

首次呼叫连接时间现在大幅减少。希望这可以帮助。

回答by Kevin

Sorry for the necro add, but this has been an ongoing struggle for me as well, and I wanted to add some info to the picture. VisualStudio itself adds a rather large component to the time. Here's the basic test, involving a bare-bones forms app and an already-running webservice hosted internally on a company server (with Generate Serialization Assembly set to true for all tests):

很抱歉添加了死灵,但这对我来说也是一个持续的斗争,我想在图片中添加一些信息。VisualStudio 本身为时间添加了一个相当大的组件。这是基本测试,涉及一个基本的表单应用程序和一个已经在公司服务器内部托管的已经运行的网络服务(所有测试的生成序列化程序集设置为 true):

Running in VS, Debug:
    First Call: 400 ms to set up client object, 450 to call function
    Second Call: 1 ms to set up client object, 14 to call function
Running as .exe, Release:
    First Call: 20 ms to set up client object, 70 to call function
    Second call: 1 ms to set up client object, 4 to call function
Running the Debug's .exe file outside of vs:
    First Call: 20 ms to set up client object, 80 to call function
    Second call: 1 ms to set up client object, 4 to call function
Running as Release within VS:
    Similar results to Debug in VS -- very slow

Short story? Visual Studio is adding a large chunk of time to the picture. Instead of ~90 ms, it's taking nearly a second. So if you're doing performance tuning, make sure you do your testing outside the VisualStudio environment.

短篇故事?Visual Studio 为图片添加了大量时间。而不是 ~90 毫秒,它需要将近一秒钟。因此,如果您要进行性能调优,请确保在 VisualStudio 环境之外进行测试。