为何Ajax调用本地并行服务器串行?WCF服务请求阻塞咨询
问题原因与解决方案
核心原因
这是Windows身份验证(NTLM/Kerberos)结合HTTPS时的会话关联锁定导致的:
- 当WCF服务配置
clientCredentialType="Windows"时,IIS会为每个已验证的用户会话维护一个请求锁定队列。默认规则下,同一用户的多个请求会被串行处理,目的是保证会话状态(如Session数据)的线程安全。 - 本地HTTP环境下,浏览器或客户端的连接复用机制、IIS的本地调试模式可能绕过了严格的会话锁定,因此请求可以并行执行;但部署到HTTPS服务器后,Windows身份验证的会话锁定逻辑被严格触发,长请求会阻塞后续同用户的短请求。
解决方案
1. 调整WCF服务的并发与实例模式
在服务类上添加特性,强制服务支持多线程并行处理:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] public class YourWcfService : IYourServiceContract { // 服务实现代码 }
InstanceContextMode.PerCall:每个请求创建独立的服务实例,避免实例级状态锁定。ConcurrencyMode.Multiple:允许多个线程同时访问服务实例,直接支持并行请求处理。
2. 禁用不必要的会话状态
如果你的服务和Web应用不需要依赖Session,可在web.config中全局禁用会话:
<system.web> <sessionState mode="Off" /> </system.web>
也可以在WCF服务行为配置中明确禁用会话关联:
<behaviors> <serviceBehaviors> <behavior name="YourServiceBehavior"> <serviceSessionMode>NotAllowed</serviceSessionMode> <!-- 其他行为配置 --> </behavior> </serviceBehaviors> </behaviors>
3. 优化IIS应用程序池设置
- 若启用Web Garden(将应用程序池的最大工作进程数设为大于1),可让不同请求分配到不同进程处理,绕过单进程内的会话锁定。但需注意:如果服务有状态依赖,可能导致状态不一致,仅适合无状态服务。
- 增大应用程序池的队列长度(默认1000),可缓解请求排队压力,但无法从根本解决串行问题。
4. 切换至Kerberos身份验证(域环境适用)
NTLM基于连接锁定会话,而Kerberos支持票据复用,同一用户的多个请求可建立独立连接,避免串行阻塞。需在域环境中完成:
- 为服务注册正确的服务主体名称(SPN)。
- 在IIS中启用Kerberos身份验证,禁用NTLM。
内容的提问来源于stack exchange,提问作者Lopo
相关产品推荐
相关产品推荐

