2

我正在尝试研究另一个开发人员报告的问题。他声称,当我们创建的 Silverlight 应用程序通过并发调用严重访问 WCF Web 服务时,这些调用开始在服务器上堆叠。他声称我们正在使用会话,因为我们正在使用身份验证方法(使用表单和 sql 的 asp.net 成员资格)。所以我创建了一个非常简单的测试应用程序

测试应用程序的屏幕截图

该应用程序允许我指定对所需 Web 服务的并发调用数,然后指示当前未完成的调用数和平均响应时间(以秒为单位)。

Web 服务本身简单地让线程休眠一秒钟

    public void DoWork()
    {
        Thread.Sleep(1000);
    }

所以我想会发生的是,如果我的同事是对的,那么调用将在服务器上堆积,因此如果有两个并发调用,平均响应将是 2 秒。然而,似乎发生的情况是,在我达到七个并发请求之前,时间保持在略高于一秒,然后它开始相对可预测地增加。

运行第二个客户端(在初始 IE 窗口旁边的 Chrome 窗口中)似乎不会影响性能(有初始打嗝)。如果您并排运行两个 IE 或两个 Chrome,则情况并非如此,那么两者似乎会相互影响,表明它们正在共享连接。

似乎提琴手也在干扰。我在没有 fiddler 的情况下运行了应用程序,有 7 个并发调用,平均每次调用大约 1.15 秒。然后我开始提琴手,时间又回到了一秒钟多一点,就好像提琴手允许额外的电话通过。

所以我的问题。这里发生了什么?节流(6 个并发请求)发生在哪里(客户端或服务器)?为什么运行提琴手会加快请求速度?

一些额外的信息。

Web 服务类有几个属性

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)]
public class DoVeryLittle : IDoVeryLittle
{
    public void DoWork()
    {
    }
}

AspNetCompatibilityRequirements 旨在允许与 asp.net 管道和身份验证集成。ServiceBehavour 的 ConcurrencyMode 和 InstanceContextMode 显然是为每个会话创建和实例化的。但是,我们使用 basicHttpBinding 作为端点,我已经看到它不支持会话,所以我对此有点困惑。

为了完整起见,这里是 web.config 中与服务相关的条目

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
4

2 回答 2

2

6 个并发连接限制听起来像是 IE 强制执行的最大值。

您没有指定您的 IE 版本,但这里是 IE8 的参考,包括更改限制的说明:Windows Internet Explorer 8 中的连接增强

我会尝试玩这个限制,看看它是否会影响你的结果。

于 2012-09-04T19:58:35.773 回答
2

好的,在一些帮助下,我找到了我需要的解释。

  • 为什么我的同事遇到并发 WCF 调用的问题?

好吧,他可能不是。在我的测试期间,我需要将服务的属性更改为以下内容才能重现问题。

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]

这会强制创建服务的单个实例,然后堆叠并发调用。原来我有attibutes

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)]

这将为每个新会话专门创建一个新服务。但是我还发现每个调用都获得了一个新会话,这是因为我们使用的是不支持会话的 BasicHttpBinding。

  • 为什么有 6 个并发呼叫的限制?

正如鲍里斯所提到的,这很可能是浏览器的限制,然后是我们使用的客户端堆栈。尽管我没有设法更改设置以查看这是否有所不同,但数字 6 在这两种情况下始终出现是完全合理的。

  • 为什么提琴手会改变这个?

我对此真的没有确定的想法,并欢迎其他任何人的意见。

于 2012-09-05T10:14:46.300 回答