You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归发起AJAX调用检查Web服务可用性时遭遇调用阻塞及超时异常的问题排查求助

排查递归AJAX检查服务可用性时的阻塞与超时问题

我来帮你分析一下这个问题的原因,以及对应的解决办法:

问题根源

你遇到的阻塞和超时问题,主要是两个核心原因导致的:

  1. 浏览器并发请求限制:所有现代浏览器都对同一域名的并发HTTP请求数有上限(一般是6个左右)。当你的Web服务未运行时,发起的AJAX请求会长时间处于pending状态(TCP连接建立超时通常需要几十秒),而你每1秒就递归发起新请求,很快就会填满浏览器的并发请求队列。后续的请求会被浏览器挂起,既无法触发success也不会触发error,看起来就像“阻塞”了。
  2. 未合理设置超时+请求堆积:即便你后来添加了超时,如果超时时间设置过长,或者没有控制请求并发,之前堆积的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:19:10