wcf - Autofac WCF - CloseChannel 在负载测试下被多次调用

标签 wcf autofac asp.net-web-api2

我正在分析一个 webapi 应用程序,该应用程序在负载下速度严重减慢(每秒 100 个请求)

应用程序调用第三方 WCF 服务。

我正在使用 dottrace,请注意 Autofac.Integration.Wcf.RegistrationExtensions.CloseChannel(T)在我的测试期间被调用 > 22k 次(100 个客户端/秒,持续 1 分钟)

DotTrace 已将此识别为热点。

我按照 Autofac WCF 集成文档注册我的 WCF:

var bookingManagerFactory = new ChannelFactory<IBookingManager>("IBookingManager");

builder.Register(c => bookingManagerFactory).SingleInstance();

builder.Register(c => c.Resolve<ChannelFactory<IBookingManager>>().CreateChannel()).UseWcfSafeRelease();

这种行为是预期的吗?

在整个应用程序中,有许多类依赖于 IBookingManager
据我了解InstancePerDependency是默认的生命周期 - 这适合我的场景吗? .InstancePerRequest() 是否更适用(在 CreateChannel() 方法上?)

最佳答案

简短的回答:这是预料之中的,而且我认为这不是问题。

深入研究一下:

Autofac 保留一次性对象,直到生命周期范围被释放,此时任何一次性对象都被释放。 (如果将对象注册为 Owned ,则可以手动处置对象,但对于 WCF 内容,我会保留它。)

WCF channel 是一个臭名昭著的挑战,因为它们是一次性的,但是 IDisposable如果 channel 出现故障(例如,如果收到错误响应),实现将抛出异常,这实际上是非常糟糕的处置设计。无论如何,这就是UseWcfSafeRelease句柄 - 它通过根据 channel 的状态正确关闭和/或中止 channel 来确保你的 channel 得到正确处理。 CloseChannel只是处理正确清理的方法。

如果您要解析一堆 channel ,那么这些 channel 都必须以某种方式进行清理。如果您看到CloseChannel被调用 22,000 次,这意味着您解决了 22,000 个需要安全清理的实例。

我不知道我会更改生命周期范围。另一个 WCF 问题是,如果 channel 发生故障,则无法重用(或重新打开)客户端代理。您已经完成了,您需要一个新 channel 。

优化解决方案的更好选择是解决 Func<IBookingManager>在你的构造函数中。每当你需要代理时,调用该函数来获取一个新代理。

public class MyConsumer
{
  private Func<IBookingManager> _factory;
  public MyConsumer(Func<IBookingManager> factory)
  {
    this._factory = factory;
  }
  public void DoWork()
  {
    this._factory().CallOperation(input);
  }
}

这有两个好处:

  1. 如果类上的方法不需要需要解析 channel ,则可以保存 channel 的创建(和处置)。
  2. 如果您处理错误(例如超时/重试),则可以在旧代理出现故障时创建新代理,并且您的类可以具有更高的容错能力。

除此之外,我认为我不会担心试图避免这种情况 CloseChannel称呼。如果您需要优化,请优化您创建的 channel 数量。

关于wcf - Autofac WCF - CloseChannel 在负载测试下被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23766670/

相关文章:

c# - 从 .NET 调用带有 WS Security 的 Web 服务

c# - 如何解析具有属性的类?

asp.net - 自承载 WCF 服务中的 Autofac 对象生命周期范围

c# - 将 HttpConfigurationExtensions 添加到 ASP.NET 项目

c# - 自定义 bool 参数绑定(bind)

c# - 为什么 Unity.Wcf 中的服务主机无法正确解析服务实例?

wcf - 不允许 JSON WCF 方法

c# - 在 WCF 服务中使用 NetworkCredential

c# - 解决 .NET Core 启动中的 Hangfire 依赖项/HttpContext

javascript - 使用 flow.js + ng-flow 将文件上传到 WebAPI 2