ASMX Web 服务第一个请求缓慢

发布于 2024-07-17 14:33:23 字数 394 浏览 2 评论 0原文

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

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

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

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.

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

﹎☆浅夏丿初晴 2024-07-24 14:33:24

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

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

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

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.

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.

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.

您的好友蓝忘机已上羡 2024-07-24 14:33:24

第一次调用 Web 服务时,或者长时间延迟后第一次调用 Web 服务时,需要启动 Web 服务。 这就是您看到延迟的地方。 之后,它就已经启动并将快速响应呼叫。 这是标准的 Web 服务行为。

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

根据要求提供更多信息。

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

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

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

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.

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

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.

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.

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

回眸一遍 2024-07-24 14:33:24

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

我们的 ASMX 看起来像这样:

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

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

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

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.

Our ASMX looked like this:

<%@ 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.

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

方圜几里 2024-07-24 14:33:24

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

首先要做的事情:

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

预编译 ASP.NET 应用程序,这样 IIS 就不需要这样做了。 请参阅“ VS 2008 Web 部署项目支持发布

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

Things to do first:

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

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

墨落成白 2024-07-24 14:33:24

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

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

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

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.

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.

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

云醉月微眠 2024-07-24 14:33:24

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

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

在我的案例中,理解延迟的关键是客户端如何处理 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>

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

bypassProxyOnLocal="false"

useDefaultWebProxy="false"

首次呼叫连接时间现已大幅缩短。
希望这可以帮助。

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)....

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.

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

This is my new binding in app.config file:

  <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):

bypassProxyOnLocal="false"

useDefaultWebProxy="false"

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

酷到爆炸 2024-07-24 14:33:24

抱歉添加了死灵,但这对我来说也是一场持续的斗争,我想在图片中添加一些信息。 VisualStudio本身给时间增加了一个相当大的组成部分。 这是基本测试,涉及一个简单的表单应用程序和一个在公司服务器内部托管的已运行的 Web 服务(所有测试的“生成序列化程序集”设置为 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

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

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):

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文