如何在IIS服务器上实现多请求并行执行?技术咨询
先结合你的日志时间线来看,核心问题出在ASP.NET的Session独占锁机制上——这是IIS/ASP.NET处理同一会话请求的默认行为,咱们一步步拆解你的疑问:
1. 为什么GET_PARENT_LIST完成后,GET_FILE_LIST启动有169ms延迟?
先梳理关键时间节点:
- 前端在11:15:39.218~39.224之间就把4个AJAX请求全部发出去了
- 服务器端GET_PARENT_LIST在39.223启动处理,39.564完成
- 但GET_FILE_LIST直到39.733才启动,中间间隔了169ms
这169ms的延迟本质是Session锁释放到下一个请求获取锁的调度时间,再加上IIS的请求队列调度开销。因为ASP.NET默认会对访问Session的请求加独占锁:当一个请求(比如GET_PARENT_LIST)开始处理时,它会锁住当前用户的Session,同一用户的其他所有请求都会被IIS挂起排队,直到这个请求处理完成、释放Session锁。你看到的169ms,就是第一个请求释放锁后,IIS从队列里取出GET_FILE_LIST请求、分配资源启动处理的时间,核心原因还是Session锁导致的串行处理逻辑。
2. 如何让Web服务收到AJAX请求后立即执行?
从日志能看到,GET_FILE_LIST前端39.220就发起了请求,但服务器39.733才开始处理,延迟了513ms——这完全是Session锁导致的排队:GET_PARENT_LIST先拿到了Session锁,后面的请求都得等它释放才能被处理。
要实现同一会话请求的并行处理,你有几个可行方案:
方案一:禁用不需要Session的Web服务的Session状态
如果你的这几个列表查询类Web服务不需要访问Session(从接口名称判断大概率不需要),可以直接在Web服务的类上添加特性:
[SessionState(SessionStateBehavior.Disabled)] public class GetParentList : System.Web.Services.WebService { // 你的服务代码 }
也可以在web.config里全局或针对特定路径禁用:
<system.web> <sessionState mode="InProc" cookieless="false" timeout="20" /> <!-- 全局禁用Session,或针对特定页面/服务配置 --> <location path="get_parent_List.asmx"> <system.web> <pages enableSessionState="false" /> </system.web> </location> </system.web>
这样这些服务的请求就不会获取Session锁,IIS可以并行处理同一会话的多个请求。
方案二:使用只读Session状态(如果必须访问Session)
如果你的服务需要读取Session但不需要修改,可以用[SessionState(SessionStateBehavior.ReadOnly)]特性。只读Session不会加独占锁,多个只读请求可以并行处理,只有写入Session的请求才会触发独占锁。
方案三:确认ASMX服务的Session默认配置
ASMX Web服务继承System.Web.Services.WebService时默认会启用Session,所以一定要显式禁用或设置为只读,才能避免锁的问题。
修改后再观察日志,你会看到多个请求的start时间和前端发起时间几乎一致,不会再出现排队延迟,实现真正的并行处理。
内容的提问来源于stack exchange,提问作者Vinit Divekar

