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

如何解决控制器中循环调用接口引发的性能缓慢及超时错误

代码优化方案

现存问题梳理

  • 逻辑bug:你写的return view逻辑放在了foreach循环体内,程序只会处理第一个id就直接返回结果,后续所有id都不会被执行,首先需要把return语句移到循环外部。
  • 性能瓶颈:当前用串行方式发起HTTP请求,每一次请求都要等待上一次返回后才会发起下一次,100次请求的总耗时是所有单次请求耗时的总和,很容易触发maximum exceed time超时错误。

具体优化方案

1. 替换串行请求为并发请求

Laravel的Http客户端原生支持并发请求,不需要逐个发送,总耗时仅等于最慢的一次请求的耗时,性能提升非常明显,优化后代码参考:

public function DeviceStatus(Request $request)
{
    $queryinput = $request->deviceNumber;
    $idsArray = array_filter(explode(" ", $queryinput)); // 过滤空的无效id
    $deviceStatus = [];
    // 生成并发请求池
    $requests = [];
    foreach ($idsArray as $id) {
        $requests[$id] = function () use ($id) {
            // 可自定义超时时间,单位为秒
            return Http::timeout(10)->get('http://127.0.0.1:8000/extapi/v12/DeviceData/ByDeviceDataNumber/'.$id);
        };
    }
    // 批量执行并发请求
    $responses = Http::pool($requests);
    // 统一处理返回结果
    foreach ($responses as $id => $response) {
        try {
            if ($response->successful()) {
                $deviceStatus[$id] = $response->json();
            } else {
                $deviceStatus[$id] = ['status' => 'error', 'msg' => '设备数据请求失败'];
            }
        } catch (\Exception $exception) {
            $deviceStatus[$id] = ['status' => 'error', 'msg' => $exception->getMessage()];
        }
    }
    // 循环结束后再返回视图
    return view('tracedevice.ectsdevicestatus', compact('deviceStatus'));
}

2. 超时配置调整

  • 如果请求量级更大,可以在方法开头添加set_time_limit(0);,临时取消当前请求的PHP运行时间上限,该配置仅对当前请求生效。

3. 可选进阶优化

  • 如果被调用的/extapi/v12/DeviceData/ByDeviceDataNumber接口支持批量查询,直接把所有id一次性传给接口,仅发起1次请求,性能比并发请求还要高。
  • 如果设备状态数据更新频率不高,可以加入缓存逻辑,把查询过的设备状态缓存起来,下次查询直接读缓存,不需要重复发起HTTP请求。

内容的提问来源于stack exchange,提问作者Melx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:24:02