【问题标题】:Avoiding GC thrashing with WSE 3.0 MTOM service使用 WSE 3.0 MTOM 服务避免 GC 抖动
【发布时间】:2010-05-20 20:17:09
【问题描述】:

由于历史原因,我有一些 WSE 3.0 Web 服务我还不能在服务器端升级到 WCF(这也是大量的工作)。

这些网络服务用于从客户端到服务器的文件传输,使用 MTOM 编码。出于兼容性的原因,这也不能在短期内改变。其次,它们是从 Java 和 .NET 调用的,因此需要跨平台,因此需要 MTOM。

它的工作原理是客户端调用“上传”WebMethod,一次发送一大块数据,因为正在传输的文件可能有千兆字节的大小。

但是,由于无法在调用 WebMethod 之前控制部分堆栈,我无法控制 Web 服务的内存使用模式。

我遇到的问题是文件大小从 50MB 左右开始,由于 GC,性能绝对会被杀死,因为 WSE 3.0 似乎将从客户端接收到的每个块缓冲在一个新的 byte[] 数组中,并且通过当我们完成 50MB 的时间时,我们将 20-30% 的时间用于 GC。

我玩过各种大小的块,从 16k 到 2MB,结果并没有太大差异。

较小的块被往返所涉及的延迟杀死,而较大的块只是推迟减速直到 GC 启动。

在减少 WSE 产生的垃圾方面有什么好主意吗?我是否可以以某种方式插入管道并临时装配可以访问客户端请求流并将其流式传输到 WebMethod 的东西?

我知道可以使用 WSE 将响应“流式传输”到客户端(尽管非常难看),但这个问题出在客户端的请求上。

【问题讨论】:

  • 另外,在 IIS7 上使用经典模式很糟糕 :)

标签: c# wcf web-services


【解决方案1】:

你已经完成了。千兆字节传输和 WSE 3.0 从来没有一起工作过——你基本上需要在 WCF 中进行流式传输。

您可以尝试使用 64 位进程并加载大量内存,这样 GC 就不是什么大问题了。升级到 .NET 4.0(应该很轻松)并使用非阻塞 GC。用 12-30gb 的内存打这个进程,你应该能多活一点。

从历史上看,所有 ASP (.net) 内容都是“批处理”的,首先收集所有数据然后发送。这意味着大件物品处理得不太好。

【讨论】:

    【解决方案2】:

    作为一种解决方法,经过一些测试,似乎可以在同一个 Web 应用程序中同时拥有 WCF 服务和旧式 ASMX Web 服务,两者都具有 .asmx 扩展名,这将让我在WCF 使用流式传输,其余服务保持不变,并保留人们用于连接的原始 URI。

    它需要一些真正的 BuildProvider 和 IHttpHandler hacking,但它确实有效。

    简而言之:

    1. 您实现了一个代理构建提供程序,它检查 .asmx 文件以确定它是 WebService 还是 ServiceHost 声明。然后,您在有问题的实际构建提供程序(System.ServiceModel.Activation.ServiceBuildProviderSystem.Web.Compilation.WebServiceBuildProvider)上调用适当的方法。请注意,您必须使用反射来实例化目标构建提供程序,因为它们是内部的。您还可以调用一些内部 BuildProvider 方法来模拟 BuildManager 所做的事情。

    2. 您实现了一个 IHttpHandlerFactory,它使用反射创建 System.ServiceModel.Activation.HttpHandler(因为它也是内部的),或者使用方便的、已经公开的 System.Web.Services.Protocols.WebServiceHandlerFactory 创建旧版 ASMX IHttpHandler。

    3. 您按如下方式配置它们(假设您在 IIS7 上使用非集成模式):

    
    
    
    <?xml version="1.0"?>
    <system.web>
        <compilation debug="true">
          <buildProviders>
            <remove extension=".asmx" />
            <add extension=".asmx" type="TestService.AsmxWcfSwitchingBuildProvider, TestService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
          </buildProviders>
        </compilation>
        <httpHandlers>
          <remove verb="*" path="*.asmx"/>
          <add path="*.asmx" verb="*" type="TestService.AsmxWcfSwitchingHttpHandlerFactory, TestService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" validate="false"/>
        </httpHandlers>
      </system.web>
    

    1. 导航到旧版 ASMX 页面。验证您是否可以看到默认页面和 WSDL。

    2. 导航到 WCF ASMX 页面。验证您是否可以看到默认页面和 WSDL。

    确保您与原始 WSDL 相同,并确保您的 SOAP 操作是正确的,等等,留给读者练习 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-05
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 2020-01-15
      相关资源
      最近更新 更多