WCF 最大实例数似乎限制为 10
我有一个简单的 WCF 服务托管在 IIS7.5 中,通过使用消息安全性和 InstanceContextMode.PerCall 的 wsHttp 绑定公开。
我有一个简单的 UI,它启动可配置数量的线程,每个线程都调用该服务。
我添加了 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 个实例?
如果我创建服务的副本,但使用具有
的 wsHttp 绑定,那么服务会愉快地创建更多实例。
I have a simple WCF service hosted in IIS7.5 exposed over a wsHttp binding using message security and InstanceContextMode.PerCall
I have a simple UI that spins up a configurable number of threads, each calling the service.
I have added the perfmon counter ServiceModel4.Instances. Regardless of the number of threads created and calling the service, perfmon shows that the service creates a maximum of 10 Instances.
My client config is as follows:
<?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>
My service config is as follows:
<?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>
The client code is as follows:
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);
}
My service code is as follows:
[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);
}
}
The service returns 400,400 for the number of threads.
Does anyone know why the service refused to create more that 10 instances?
If I create a copy of the service but with a a wsHttp binding that has <security mode="None"/>
then the service happily created many more instances.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是在 Windows Server 还是 Windows 7 上进行测试?我问的原因是客户端操作系统版本上的 IIS 有 10 个连接限制。这是为了防止客户端操作系统在服务器环境中使用。
Are you testing on a Windows Server or Windows 7? The reason I ask is that IIS on the client OS versions has a 10 connection limit. This is to prevent the client OS from being used in a server environment.
MaxConcurrentSessions 文档提到了对来自同一 AppDomain 的客户端请求。您的示例代码基本上是在服务上使用相同的套接字。由于每个客户端都会进行一些限制,这可能会影响您的服务行为。另外,10 恰好是 MaxConcurrentSessions 的默认值,因此您的配置可能没有更改 WCF 默认值。
启用安全性会影响总线程数,因为它为每个客户端建立一个“会话”,以便发送的每个请求不需要在每次调用时进行身份验证。这些安全“会话”计入 MaxConcurrentSessions 总数。
The MaxConcurrentSessions documentation mentions an optimization for client requests that come from the same AppDomain. Your sample code is basically hitting the same socket on the service. Since there is some throttling done per client, that may be affecting your service behavior. Also, 10 happens to be the default value for MaxConcurrentSessions so it may be that your config is not changing the WCF default value.
Enabling security affects the total threads because it establishes a "session" per client so that each request sent does not need to be authenticated on every call. Those security "sessions" count toward the MaxConcurrentSessions total.
您是否在同一台计算机上运行客户端和服务器?然后他们可能会争夺可用的线程。
如果您在不同的 PC 上运行,请确保您已在客户端和服务器上完成以下配置更改。
http://www.codeproject.com/KB/webservices/quickwins.aspx
客户端向同一服务器生成的请求可能不会超过 10 个。因此,请首先在客户端和服务器上尝试上述配置。
当然,您必须拥有 Windows Server。否则就是Windows 7上的IIS限制。
Are you running the client and server on the same machine? Then they might be fighting for available threads.
If you are running on a different PC, please ensure you have done the following config changes on both client and server.
http://www.codeproject.com/KB/webservices/quickwins.aspx
It is possible that the client is not generating more than 10 requests to the same server. So, please try the above configs first on both client and server.
And of course, you must have a Windows Server. Otherwise it will be the IIS limit on Windows 7.