Azure App Service请求耗时120秒,IIS却显示仅31ms,原因何在?
这个问题我之前协助排查过类似场景,结合你提到的「最后0字节响应块延迟119秒(刚好是2分钟默认超时阈值)」的细节,核心问题大概率出在Azure App Service的响应缓冲/分块传输处理逻辑上,给你几个针对性的排查和解决方向:
检查并调整响应缓冲配置
Azure App Service默认启用了响应缓冲机制,当你的应用代理分块编码的gzip响应时,IIS或后端的ARR(Application Request Routing)可能会等待整个响应完成才向客户端推送内容。而最后一块0字节的结束标识会触发默认的2分钟超时,才被发送出去。
你可以通过web.config关闭不必要的缓冲或调整相关限制:<system.webServer> <!-- 禁用动态压缩,避免Azure重新处理上游已压缩的响应 --> <urlCompression doStaticCompression="true" doDynamicCompression="false" /> <httpCompression> <dynamicTypes> <clear /> </dynamicTypes> </httpCompression> <!-- 取消响应缓冲限制 --> <serverRuntime enabled="true" responseBufferLimit="0" /> </system.webServer> <system.web> <httpRuntime responseBufferLimit="0" /> </system.web>确保分块传输头正确传递
你的应用作为代理,要严格保留上游返回的Transfer-Encoding: chunked头,同时不要设置Content-Length头(分块传输不需要这个头)。如果上游返回了Content-Length,必须在代理时移除这个头,避免Azure App Service的缓冲逻辑冲突。
另外,要确保上游的Content-Encoding: gzip头被完整传递,不要让应用重复压缩响应内容——重复压缩会导致Azure无法正确识别分块结构,进而触发超时。调整ARR超时阈值
Azure App Service背后的ARR组件默认响应超时为2分钟(120秒),这刚好和你遇到的延迟时间匹配。你可以通过web.config缩短ARR的超时时间,避免不必要的等待:<system.webServer> <proxy enabled="true" timeout="00:00:10" /> <!-- 调整为符合业务场景的超时值,比如10秒 --> </system.webServer>注意:这个值需要和你的应用处理时间匹配,避免正常请求被提前中断。
验证应用级的分块发送逻辑
虽然你的应用日志显示仅耗时25ms,但要确认应用是否在发送完所有响应块后,立即发送了0字节的结束块。有些代理框架可能会在分块发送时存在延迟,比如等待连接状态变化才触发结束块发送,可以检查代码中是否有明确的分块结束标识发送逻辑。
内容的提问来源于stack exchange,提问作者MikeBrno

