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

AWS Amplify部署NextJS后流式API失效且超时30秒求助

问题描述

在AWS Amplify上部署的Next.js应用中,针对耗时较长的API调用采用了流式响应方案,本地开发环境运行正常,但部署后流式功能失效,且请求会因超过30秒而超时。前端处理流式响应的代码如下:

try {
      setLoading(true);
      setAnswer('');
      const res = await fetch(`/api/test?question=${question}`);
      if (res.ok) {
        const reader = res?.body?.getReader();
    
        const processStream = async () => {
          while(true) {
            const {done, value} = await reader?.read() || {};

            if (!value) {
              setLoading(false);
              break;
            }

            if(done) {
              setLoading(false);
              break;
            }

            let chunk = new TextDecoder('utf-8').decode(value)

            chunk = chunk.replace(/^data: /, '');

            setAnswer((prev) => prev + chunk);
          }
        }
    
        processStream().catch(err => console.log('--stream error--', err))
  
      } else {
        setAnswer("Sorry, there was an error fetching your answer. Please try again later.");
      }
    } catch (error) {
      console.error("Error fetching answer:", error);
      setAnswer("Sorry, there was an error fetching your answer. Please try again later.");
    }
解决方案

1. 调整AWS Amplify的超时与流式支持配置

AWS Amplify默认请求超时为30秒,且CDN会缓冲响应导致流式失效,需在项目根目录的amplify.yml中修改配置:

  • 延长API对应的Lambda函数超时时间(最大可设为15分钟)
  • 为API路径添加分块传输响应头
  • 禁用API路径的CDN缓存

示例amplify.yml配置片段:

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm install
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
headers:
  - pattern: /api/*
    headers:
      - key: Transfer-Encoding
        value: chunked
      - key: Cache-Control
        value: no-cache, no-store, must-revalidate
function:
  your-api-function-name:
    timeout: 900 # 15分钟,按需调整

2. 确保Next.js API路由正确实现流式响应

Pages Router(pages/api/test.js)

使用res.write()和res.flush()手动输出分块内容,同时设置正确响应头:

export default async function handler(req, res) {
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.setHeader('Transfer-Encoding', 'chunked');
  res.setHeader('Cache-Control', 'no-cache');

  // 模拟流式数据返回逻辑
  const dataChunks = ['第一部分内容', '第二部分内容', '第三部分内容'];
  for (const chunk of dataChunks) {
    res.write(`data: ${chunk}\n\n`);
    await new Promise(resolve => setTimeout(resolve, 1000));
    res.flush(); // 强制发送当前缓冲区内容
  }

  res.end();
}

App Router(app/api/test/route.js)

使用Next.js流式API返回ReadableStream:

export async function GET(req) {
  const { searchParams } = new URL(req.url);
  const question = searchParams.get('question');

  const stream = new ReadableStream({
    async start(controller) {
      // 模拟流式数据生成逻辑
      const dataChunks = ['第一部分内容', '第二部分内容', '第三部分内容'];
      for (const chunk of dataChunks) {
        controller.enqueue(new TextEncoder().encode(`data: ${chunk}\n\n`));
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
      controller.close();
    }
  });

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
      'Transfer-Encoding': 'chunked',
      'Cache-Control': 'no-cache'
    }
  });
}

3. 优化前端请求配置

确保fetch请求禁用压缩(避免CDN缓冲完整响应),添加必要配置:

const res = await fetch(`/api/test?question=${question}`, {
  headers: {
    'Accept-Encoding': 'identity' // 禁用gzip压缩
  },
  keepalive: true
});

4. 检查Lambda执行角色权限

如果API调用依赖其他AWS服务(如大模型服务、存储服务等),确保Lambda执行角色拥有对应权限,避免因权限问题导致响应停滞超时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:45:00