Web Service 请求 60s 问题调查【未解决】
🏷️ ASP.NET
根据听云的统计,很多慢事务的时间都在 60 秒左右。
而且返回的 HttpCode 为 500(服务器内部错误)。但是所有的接口的调用都是有 TryCatch 的,如果业务处理发生了异常,也是可以正常返回的。
对比了正常和异常的请求,发现异常请求中 ScriptModule.OnPostAcquireRequestState
方法执行了很长时间,之后直接调用 SessionStateModule.OnEndRequest
结束了请求。
而正常流程下还会有执行很多接口中的处理,之后才会调用 SessionStateModule.OnReleaseState
结束请求。
异常请求的流程
- Global.Application_BeginRequest
- WindowsAuthenticationModule.OnEnter
- ScriptModule.AuthenticateRequestHandler
- Global.Application_AuthenticateRequest
- DefaultAuthenticationModule.OnEnter
- ServiceHttpModule.BeginProcessRequest
- UrlAuthorizationModule.OnEnter
- FileAuthorizationModule.OnEnter
- OutputCacheModule.OnEnter
- UrlRoutingModule.OnApplicationPostResolveRequestCache
- SessionStateModule.BeginAcquireState
- ProfileModule.OnEnter
- ScriptModule.OnPostAcquireRequestState
- SessionStateModule.OnEndRequest
- ProfileModule.OnLeave
- ScriptModule.EndRequestHandler
正常请求的流程
- Global.Application_BeginRequest
- WindowsAuthenticationModule.OnEnter
- ScriptModule.AuthenticateRequestHandler
- Global.Application_AuthenticateRequest
- DefaultAuthenticationModule.OnEnter
- ServiceHttpModule.BeginProcessRequest
- UrlAuthorizationModule.OnEnter
- FileAuthorizationModule.OnEnter
- OutputCacheModule.OnEnter
- UrlRoutingModule.OnApplicationPostResolveRequestCache
- SessionStateModule.BeginAcquireState
- ProfileModule.OnEnter
- ScriptModule.OnPostAcquireRequestState
- ImplicitAsyncPreloadModule.OnEnter
- RedisNativeClient.GetBytes
- ...
- ...
- SessionStateModule.OnReleaseState
- OutputCacheModule.OnLeave
- ProfileModule.OnLeave
- ScriptModule.EndRequestHandler
下面的描述摘自 ASP.Net 请求处理机制初步探索之旅 - Part 3 管道 :
从上面的介绍中可以看到,第九到第十个事件是:
AcquireRequestState
,PostAcquireRequestState
。这期间首先会接收到浏览器发过来的 SessionId ,然后先会将IHttpHandler
接口尝试转换为IRequiresSessionState
接口,如果转换成功,ASP.NET 会根据这个 SessionId 到服务器的 Session 池 中去查找所对应的 Session 对象,并将这个 Session 对象 赋值到 HttpContext 对象 的 Session 属性。如果尝试转换为IRequiresSessionState
接口不成功,则不加载 Session。
所以准备禁用 Session,改为通过自定义的处理来创建这个 SessionId,实际的 Session 数据则保存在 Redis 中。
实际发布到生产后发现并没有解决任何问题。下面是修改后的异常请求流程。
禁用 Session 后异常请求的流程
- Global.Application_BeginRequest
- WindowsAuthenticationModule.OnEnter
- ScriptModule.AuthenticateRequestHandler
- Global.Application_AuthenticateRequest
- DefaultAuthenticationModule.OnEnter
- ServiceHttpModule.BeginProcessRequest
- UrlAuthorizationModule.OnEnter
- FileAuthorizationModule.OnEnter
- OutputCacheModule.OnEnter
- UrlRoutingModule.OnApplicationPostResolveRequestCache
- ProfileModule.OnEnter
- ScriptModule.OnPostAcquireRequestState
- ProfileModule.OnLeave
- ScriptModule.EndRequestHandler
怀疑可能出现问题的地方
IIS 出现堵塞- 请求并没有多少,也没有排队的请求
Redis 缓存查询超时如果 Redis 查询超时了,应该有会异常的日志,而且 HttpCode 也不可能为 500
- 听云记录出错
- 有可能吗?不知道。
请求超时请求超时的话,HTTP Code 应该为 408 才对
IIS 获取/创建 Session 数据超时?禁用 Session 后仍然还是没有任何改善