我在IIS7.5中托管了一个简单的WCF服务,该服务使用消息安全性和InstanceContextMode.PerCall
通过wsHttp绑定公开我有一个简单的用户界面,可以旋转可配置数量的线程,每个线程都调用该服务。
我添加了perfmon计数器ServiceModel4.Instances。无论创建的线程数和调用服务的数量如何,perfmon都会显示该服务最多可创建10个实例。
我的客户端配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService3">
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/NGCInstancing/Service3.svc/~/Service3.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService3"
contract="NGCSecPerCall.IService3" name="WSHttpBinding_IService3">
<identity>
<servicePrincipalName value="host/RB-T510" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
我的服务配置如下:
<?xml version="1.0"?>
<system.serviceModel>
<configuration>
<behaviors>
<serviceBehaviors>
<behavior name="SecPerCallBehaviour">
<serviceThrottling maxConcurrentCalls="30" maxConcurrentSessions="1000"
maxConcurrentInstances="30" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="BindingMessageSecPerCall" >
<security mode="Message">
<!-- it's by setting establishSecurityContext to false that we enable per call instancing with security -->
<message establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="ServiceInstancingDemo.Service3" behaviorConfiguration="SecPerCallBehaviour">
<endpoint address="~/Service3.svc"
binding="wsHttpBinding" bindingConfiguration="BindingMessageSecPerCall"
contract="ServiceInstancingDemo.IService3" />
</service>
</services>
</configuration>
</system.serviceModel>
客户端代码如下:
private void btnSecPerCall_Click(object sender, EventArgs e)
{
int i;
int requests;
int delay;
lblStatus.Text = "";
DateTime startTime = DateTime.Now;
this.listBox1.Items.Add("start time=" + DateTime.Now);
delay = Convert.ToInt16(txtDelay.Text);
requests = Convert.ToInt16(txtRequests.Text);
Task<string>[] result;
result = new Task<string>[requests];
for (i = 0; i < requests; i++)
{
result[i] = Task<string>.Factory.StartNew(() => _ngcSecPerCall.WaitThenReturnString(delay));
}
for (i = 0; i < requests; i++)
{
this.listBox1.Items.Add(result[i].Result);
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime - startTime;
lblStatus.Text = "Finished! Time taken= " + ts.Seconds + " seconds";
this.listBox1.Items.Add("end time=" + DateTime.Now);
}
我的服务代码如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service3 : IService3
{
private int m_counter;
public string WaitThenReturnString(int waitMilliSeconds)
{
System.Threading.Thread.Sleep(waitMilliSeconds);
int maxT, workCT;
System.Threading.ThreadPool.GetMaxThreads(out maxT, out workCT);
m_counter++;
return String.Format("Incrementing counter to {0}.\r\nSession Id: {1}. Threads {2}, {3}", m_counter, OperationContext.Current.SessionId, maxT, workCT);
}
}
服务返回线程数400,400。
有谁知道服务拒绝创建更多10个实例的原因?
如果我创建了服务的副本但是使用了具有<security mode="None"/>
的wsHttp绑定,那么该服务会愉快地创建更多实例。
答案 0 :(得分:20)
您是在Windows Server或Windows 7上进行测试吗?我问的原因是客户端操作系统版本上的IIS有10个连接限制。这是为了防止客户端操作系统在服务器环境中使用。
答案 1 :(得分:2)
MaxConcurrentSessions documentation提到了来自同一AppDomain的客户端请求的优化。您的示例代码基本上是在服务上命中相同的套接字。由于每个客户端都有一些限制,这可能会影响您的服务行为。此外,10恰好是MaxConcurrentSessions的默认值,因此您的配置可能不会更改WCF默认值。
启用安全性会影响总线程数,因为它会为每个客户端建立一个“会话”,以便每次调用时都不需要对发送的每个请求进行身份验证。那些安全“会话”计入MaxConcurrentSessions总数。
答案 2 :(得分:1)
您是否在同一台计算机上运行客户端和服务器?然后他们可能会争夺可用的线程。
如果您在其他PC上运行,请确保您已在客户端和服务器上完成以下配置更改。
http://www.codeproject.com/KB/webservices/quickwins.aspx
客户端可能不会向同一服务器生成超过10个请求。所以,请先在客户端和服务器上尝试上述配置。
当然,您必须拥有Windows Server。否则它将是Windows 7上的IIS限制。