Firecrawl Scraping 负载测试实战:从 61.6% 失败率到稳定承载 9000 请求的压测调优记录

发布时间:2026/9/30 6:44:27
Firecrawl Scraping 负载测试实战:从 61.6% 失败率到稳定承载 9000 请求的压测调优记录 网页爬虫后端AI 应用【免费下载链接】firecrawlThe web data API to search, scrape, and interact at scale. 项目地址https://gitcode.com/GitHub_Trending/fi/firecrawl点击查看免费下载本篇技术指南以 Firecrawl 开源仓库中 测试套件压测结果记录 为主体完整还原第 2 轮负载测试9000 请求、4 阶段加压、61.6% 失败率的实验环境、Artillery 压测配置与逐项指标分析并结合同一仓库中第 38 轮测试记录给出 CPU 瓶颈定位、Fly.io 并发限流配置、Artillery 超时调整与弹性伸缩Autoscaling等可落地的优化路径。读者读完将掌握如何用 Artillery 对 Firecrawl 的/scrape与/crawl接口进行分阶段加压测试、如何解读压测报告中的超时与响应时间指标以及如何通过 Fly.io 并发配置与 worker 参数迭代完成一轮完整的性能调优闭环。测试背景为什么要做第 2 轮压测Firecrawl 提供 search、scrape、crawl、map 等网页数据抓取 API。为验证服务在大流量下的稳定性仓库维护者在 apps/test-suite 目录下搭建了基于 Artillery 的负载测试体系并连续执行了多轮测试仓库中保留了 tests-1-5 与 tests-6-7 两组共 8 份报告。第 1 轮测试详见 load-test-1.md仅以arrivalRate: 10恒定速率运行 60 秒600 个请求全部返回 HTTP 200平均响应时间 1380.1 ms两台机器 CPU 峰值约 50%但压测后内存未回落到基线提示可能存在内存泄漏。第 2 轮测试的目标正是针对更高负载验证系统极限将请求量放大 15 倍至 9000并通过 4 个阶段模拟爬坡—峰值—冷却的真实流量曲线观察系统在 CPU 打满、请求排队等极端场景下的表现。测试环境两台 2048MB 的 Fly.io 应用机器第 2 轮压测的实验环境为两台 Fly.io 上运行的mia迈阿密区域应用机器MachineSize/CPUe286de4f711e86 mia (app)performance-cpu-1x2048MB73d8dd909c1189 mia (app)performance-cpu-1x2048MB单核 CPU 搭配 2048MB 内存的机型用于检验默认部署未开启自动扩容在突增流量下的承载能力。从后续轮次load-test-3.md可以看到这套环境随后补充了 3 台paused状态的机器用于测试自动扩缩容说明第 2 轮结果直接触发了基础设施层面的调优决策。压测配置9000 请求 · 7 分 11 秒 · 4 阶段加压第 2 轮使用的 Artillery 场景配置记录在测试报告中与仓库根部的 load-test.yml 一脉相承。压测负载由 4 个 phase 组成# load-test.yml - duration: 60 arrivalRate: 10 # Initial load - duration: 120 arrivalRate: 20 # Increased load - duration: 180 arrivalRate: 30 # Peak load - duration: 60 arrivalRate: 10 # Cool downInitial load60s10 req/s预热阶段建立初始连接与并发基线Increased load120s20 req/s翻倍加压观察系统在持续增长流量下的表现Peak load180s30 req/s峰值阶段持续 3 分钟逼近系统吞吐上限Cool down60s10 req/s回落到初始速率观察资源是否随负载释放。按各阶段速率累加共产生 9000 个请求。每个虚拟用户vuser对应一次/scrape调用——从报告中的vusers.created_by_name.Scrape a URL: 9000可以确认。仓库中的完整 Artillery 配置参考虽然第 2 轮报告只摘录了 phases 部分仓库根部的 load-test.yml 给出了完整可运行的配置包含第 2 轮报告未展开的http.timeout与场景scenario定义config: target: https://staging-firecrawl-scraper-js.fly.dev/v0 http: timeout: 30 phases: - duration: 60 arrivalRate: 1 # Initial load - duration: 120 arrivalRate: 2 # Increased load - duration: 180 arrivalRate: 3 # Peak load - duration: 60 arrivalRate: 1 # Cool down defaults: headers: Authorization: Bearer YOUR_API_KEY scenarios: - name: Crawl a URL flow: - post: url: /crawl json: url: https://rsseau.fr crawlerOptions: limit: 100 pageOptions: onlyMainContent: true capture: - json: $.jobId as: job_id - think: 10 - get: url: /crawl/status/{{ job_id }} capture: - json: $.status as: crawl_status until: - condition: equals value: completed variable: crawl_status retry: count: 20 wait: 10这个配置展示了两个关键工程细节一是target指向staging环境staging-firecrawl-scraper-js.fly.dev/v0压测必须与生产隔离二是场景中通过capture从/crawl响应里提取$.jobId再轮询/crawl/status/{jobId}直到状态变为completed模拟真实的异步抓取任务提交—轮询链路。think: 10与retry/wait组合用于控制轮询节奏避免空转打爆接口。提示当前 load-test.yml 的 phases 和场景分别对应/crawl的注释版/scrape与/search场景以注释形式保留Scrape a URL、Search for a query。第 2 轮报告中的 9000 个Scrape a URLvuser 说明测试时使用的是 scrape 场景可按需在文件中切换启用。如何运行这套压测按照 test-suite README 的说明运行负载测试需要先全局安装 Artillery再执行artillery runnpm install -g artillery artillery run load-test.yml若希望把完整 JSON 报告输出到 load-test-results 目录与仓库中test-run-report.json的做法一致可以使用仓库 package.json 中定义的脚本npm run test:load # 等价于artillery run --output ./load-test-results/test-run-report.json load-test.yml运行前请将配置中的YOUR_API_KEY替换为有效的 API Key并将target指向自己的测试环境。Artillery 报告逐项解读9000 请求、5473 次超时第 2 轮压测的核心结果如下报告日期 13:50:08 -0300MetricValueerrors.ETIMEDOUT5473errors.Failed capture or match73http.codes.2003454http.codes.40164http.codes.4029http.downloaded_bytes0http.request_rate21/sechttp.requests9000http.response_time.min929http.response_time.max9919http.response_time.mean3682.1http.response_time.median3395.5http.response_time.p958024.5http.response_time.p999607.1http.responses3527vusers.completed3454vusers.created9000vusers.created_by_name.Scrape a URL9000vusers.failed5546vusers.session_length.min1127.6vusers.session_length.max9982.2vusers.session_length.mean3730.6vusers.session_length.median3464.1vusers.session_length.p957865.6vusers.session_length.p999607.1关键指标解读errors.ETIMEDOUT 5473压倒性的失败来源。所谓 ETIMEDOUT 是 Artillery 在客户端侧捕获的 TCP 连接超时——即客户端在http.timeout: 30秒内未能收到响应。5473 个超时占总请求的 60.8%是 61.6% 失败率的绝对主因。vusers.failed 554661.6%vuser 总数 9000成功 3454失败 5546。其中 5473 个为超时73 个为Failed capture or match响应返回但 JSON 提取断言未匹配说明服务端可能在过载时返回了非预期内容。http.responses 3527与 200/401/402 之和一致3454 64 9 3527。除 200 外出现了 64 个 401鉴权失败与 9 个 402Payment Required通常是配额/计费限制表明过载环境下部分请求在进入处理流程前就被网关或鉴权层拒绝。http.downloaded_bytes 0Artillery 未统计到下载字节间接说明大量请求未能完整走完抓取流程拿到正文内容。响应时间分布严重恶化mean 3682.1ms、median 3395.5ms而 p95 高达 8024.5ms、p99 9607.1ms最大值 9919ms 逼近客户端超时上限 30s 的 1/3。尾部延迟p95/p99与中位数之间拉出 2.42.8 倍差距是典型的排队拥塞特征——请求在队列中等待服务端 CPU 已无法及时处理。session_length 与 response_time 高度一致p99 同为 9607.1ms说明会话耗时几乎全部消耗在 HTTP 请求往返上而非客户端脚本逻辑。机器资源曲线CPU 双机打满是瓶颈铁证测试报告中引用的资源监控图 metrics-test-2.png 直观呈现了四个面板内存利用率系统总内存稳定在 1.8GiB 左右两个节点的内存使用在 0512MiB 区间平稳波动无异常飙升——内存不是本轮瓶颈CPU 利用率测试启动后两个节点快速爬升13:4613:50 期间黄色节点73d8dd909c1189逼近 100%蓝色节点e286de4f711e86峰值约 95%属于满负载运行应用并发数随负载同步增长峰值约在 13:48 出现单节点并发接近 1701905 分钟负载均值与 CPU、并发曲线吻合13:50 左右达到峰值约为系统容量的 90%测试结束后回落。两张图报告截图 文字描述共同指向同一结论CPU 是第 2 轮的硬瓶颈。两台单核机器在持续加压下双双打满请求在队列中排队最终在客户端 30s 超时窗口内无法完成产生数千个 ETIMEDOUT。结论与下一步从打满即崩到可伸缩架构本轮结论性能系统在 9000 请求下力不从心产生 5473 个超时平均响应时间 3682.1msCPU 利用率两台机器均达到 100%造成严重性能退化与高失败率。仓库后续轮次的调优路径可复用的完整闭环第 2 轮报告给出的 Next Step 只有一句——在 Fly.io 上实现自动扩缩容方案并用相同配置复测。而仓库中保留的第 38 轮报告恰好完整记录了这一建议被逐步落实的全过程构成一套可借鉴的性能调优闭环Step 1 —— 开启 Fly.io 自动扩缩容第 3 轮见 load-test-3.md在fly.staging.toml中为 http 服务配置并发限流与弹性伸缩# fly.staging.toml [http_service.concurrency] type requests hard_limit 100 soft_limit 75测试环境变为 5 台机器2 台常开 3 台初始 paused。压测中 3 台机器自动扩容启动超时从 5473 降至 6537.3%平均响应时间降到 3037.2ms但仍有 2 个 502。结论自动扩容有效但 soft limit 触发偏慢。Step 2 —— 调整软/硬限流参数第 4 轮见 load-test-4.md将 soft_limit 降到 50、hard_limit 保持 100期望机器更早启动[http_service.concurrency] type requests hard_limit 100 soft_limit 50结果502 消失说明机器启动变快、不再因排队被网关拒绝但超时反弹到 132914.8%平均响应时间 3547.9ms。结论需要转向调整 Artillery 侧的超时配置。Step 3 —— 提高 Artillery 客户端超时第 5 轮见 load-test-5.mdhttp: timeout: 30在 30s 客户端超时下9000 请求中 8996 个成功仅 4 个 5020.04%失败率断崖式下降。但代价是平均响应时间拉长到 5661.8ms、峰值 18924ms——系统在排队硬扛而非快速处理。这轮的意义在于调整压测客户端超时需要与真实用户体验/网关超时统一口径过短的客户端超时会高估系统故障。Step 4 —— 转向 /crawl 异步链路压测第 68 轮见 load-test-6.md、load-test-7.md、load-test-8.md抓取策略切换为 fire-engine 后压测对象变成app worker fire-engine三层拓扑。第 7 轮中 fire-engine 机器在处理队列 22 分钟后 CPU/内存双双打满导致测试中断暴露出 worker 数与资源管理缺陷第 8 轮将NUM_WORKERS_PER_QUEUE从 8 提升到 12fire-engine 机器 CPU 仍达 99%、内存 92%但队列能全部处理完同时暴露了 autoscaling 未按预期启动备用 worker 机器的问题。Step 5 —— 沉淀为自动化脚本整个压测流程最终固化在 package.json 的test:load脚本与 load-test.yml 中报告统一输出到 load-test-results 目录形成改配置 → 跑压测 → 存报告 → 分析 → 再改配置的可持续迭代机制。实战经验总结综合第 28 轮共 7 份报告可以提炼出 Firecrawl以及任何基于 Fly.io 的抓取 API 服务压测与调优的几条核心经验瓶颈定位要分资源维度第 2 轮中 CPU 打满而内存充裕说明调优重点在计算能力/并发承载而非内存扩容抓取类服务的 HTML 解析、渲染与转 Markdown 均为 CPU 密集操作Firecrawl 的文档解析、抓取转换逻辑集中在 apps/api/src 下单核机器扛不住高峰并发。失败率要区分真故障与客户端超时假象ETIMEDOUT 与 502 的成因完全不同——前者是客户端等不到响应后者是网关拒绝。第 5 轮证明调高客户端超时能大幅降低失败率但这不代表系统更快只代表队列更深。弹性伸缩需要软硬限配合soft_limit决定何时启动新机器越低越早扩容hard_limit决定网关何时拒绝新请求越低越早保护。第 3、4 轮的对比说明两者需要在扩容及时性与保护性拒绝之间反复校准。异步任务链路要压到真正的执行层/crawl 的提交接口响应快第 6 轮平均 838.1ms真正的压力在 worker 与 fire-engine 执行层第 7 轮 22 分钟打满。只压 API 入口会漏掉执行层瓶颈worker 数量如NUM_WORKERS_PER_QUEUE与自动扩容策略必须纳入观测。用脚本固化压测流程把 Artillery 配置、报告输出路径写进 package.json让性能回归成为可重复的工程动作而不是一次性手工操作。相关资源导航本文主体第 2 轮压测报告及其同目录下的 load-test-1.md、load-test-3.md、load-test-4.md、load-test-5.md压测工具链Artillery 配置、package.json 脚本、测试套件说明后续轮次/crawl 与 fire-engine 压测、load-test-7.md、load-test-8.md被压测的服务端实现Firecrawl API 源码位于 apps/api/src其中 /scrape 与 /crawl 路由 及 scraper 相关模块 是理解压测行为背后逻辑的入口说明本文数据均来自仓库 apps/test-suite/load-test-results 下的原始压测报告未做任何外部假设压测环境为 Firecrawl 的 staging 部署staging-firecrawl-scraper-js.fly.dev结果反映该特定机型performance-cpu-1x2048MB与特定配置组合下的表现生产环境复测时应以自身部署参数为准。赞分享网页爬虫后端AI 应用【免费下载链接】firecrawlThe web data API to search, scrape, and interact at scale. 项目地址https://gitcode.com/GitHub_Trending/fi/firecrawl点击查看免费下载相关推荐Firecrawl 抓取接口负载压测实战9000 并发请求下的 30 秒超时调优与稳定性验证Firecrawl 抓取接口负载压测实战9000 并发请求下的 30 秒超时调优与稳定性验证 本篇指南以 Firecrawl 开源仓库中记录的第五轮抓取Sc网页爬虫后端AI 应用Firecrawl 负载测试实战用 Artillery 压测 Scrape 接口与 Fly.io 性能调优Firecrawl 负载测试实战用 Artillery 压测 Scrape 接口与 Fly.io 性能调优 本指南以 Firecrawl 开源仓库中 load网页爬虫后端AI 应用Vegeta HTTP负载测试终极指南从零开始掌握9000请求的威力Vegeta HTTP负载测试终极指南从零开始掌握9000请求的威力 Vegeta是一款功能强大的HTTP负载测试命令行工具和Go库专门设计用于以恒定请求上一篇orx instance完整教程创建、列出与销毁计算实例下一篇FoundationDB 读写路径深度解析事务读路径、写路径与并发排序机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询