递归发起AJAX调用检查Web服务可用性时遭遇调用阻塞及超时异常的问题排查求助
排查递归AJAX检查服务可用性时的阻塞与超时问题
我来帮你分析一下这个问题的原因,以及对应的解决办法:
问题根源
你遇到的阻塞和超时问题,主要是两个核心原因导致的:
- 浏览器并发请求限制:所有现代浏览器都对同一域名的并发HTTP请求数有上限(一般是6个左右)。当你的Web服务未运行时,发起的AJAX请求会长时间处于
pending状态(TCP连接建立超时通常需要几十秒),而你每1秒就递归发起新请求,很快就会填满浏览器的并发请求队列。后续的请求会被浏览器挂起,既无法触发success也不会触发error,看起来就像“阻塞”了。 - 未合理设置超时+请求堆积:即便你后来添加了超时,如果超时时间设置过长,或者没有控制请求并发,之前堆积的
pending请求仍然会占用并发名额。就算服务恢复,这些排队的请求可能先触发超时错误,继续递归发起新请求,导致新请求还是被阻塞在队列里,出现“服务恢复仍超时”的假象。
另外还要注意一个细节:你的AJAX请求URL缺少协议前缀(http://),有些浏览器会把localhost:8085当成当前页面的相对路径,导致请求发送到错误的地址,这也可能加重问题。
修复后的代码示例
我们可以通过控制请求并发和设置合理超时来解决这个问题:
// 用一个标志位确保同一时间只有一个检查请求在运行 let isCheckingService = false; function checkWebService() { // 如果正在检查,直接返回,避免重复发起请求 if (isCheckingService) return; isCheckingService = true; console.log("发起服务可用性检查"); $.ajax({ // 补上http协议前缀,确保请求地址正确 url: "http://localhost:8085/login/checkWebServiceIsRunning", type: 'GET', // 设置合理的超时时间,比如500毫秒,避免请求长时间pending timeout: 500, success: (response) => { console.log("服务已恢复正常"); isCheckingService = false; // 这里可以根据需求选择:如果服务恢复就停止检查,或者继续定期检查 // 比如需要持续监控的话,可以保留setTimeout,否则去掉即可 }, error: (jqXHR, textStatus, errorThrown) => { console.log("服务不可用,错误类型:", textStatus); isCheckingService = false; // 1秒后再次发起检查 setTimeout(() => { checkWebService(); }, 1000); } }); }
关键优化点说明
- 并发控制标志位:
isCheckingService确保同一时间只有一个AJAX请求在执行,彻底避免请求堆积问题。 - 合理超时设置:
timeout:500让请求在500毫秒内没有响应就触发错误,避免请求长时间占用并发名额。 - 修正请求URL:添加
http://前缀,确保请求发送到正确的地址。
这样修改后,无论是服务未运行时的循环检查,还是服务恢复后的正常响应,都能稳定工作,不会再出现阻塞或异常超时的情况。
内容的提问来源于stack exchange,提问作者kailashdesiti
相关产品推荐
相关产品推荐

