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

如何解决Heroku上Playwright爬虫应用频繁崩溃问题?

针对Heroku上Playwright爬虫频繁崩溃的调整方案
  • 强制每次任务启动全新浏览器实例
    绝对不要复用浏览器上下文或页面实例,每次爬虫任务执行时都调用browser.launch()创建全新实例,任务结束后必须调用browser.close()彻底关闭。Heroku容器资源有限,复用实例极易引发连接泄漏,进而触发ENOTCONN错误。示例代码:

    const { chromium } = require('playwright');
    
    async function runCrawler() {
      let browser;
      try {
        browser = await chromium.launch({
          headless: true,
          args: ['--no-sandbox', '--disable-setuid-sandbox'] // 必须保留Heroku适配参数
        });
        const page = await browser.newPage();
        // 你的爬虫逻辑代码
      } catch (err) {
        console.error('爬虫执行出错:', err);
      } finally {
        if (browser) await browser.close(); // 无论成功失败都要关闭浏览器
      }
    }
    
  • 添加资源限制与错误重试机制
    Heroku Eco实例仅512MB内存,运行Chromium很容易资源耗尽。启动浏览器时添加内存相关限制参数,同时给页面跳转、资源加载等关键操作增加重试逻辑:

    // 启动浏览器时追加资源限制参数
    browser = await chromium.launch({
      headless: true,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--memory-pressure-off',
        '--disable-dev-shm-usage' // 避免/dev/shm空间不足问题
      ]
    });
    
    // 封装重试函数
    async function withRetry(fn, retries = 2) {
      try {
        return await fn();
      } catch (err) {
        if (retries > 0 && (err.message.includes('ENOTCONN') || err.message.includes('Resource temporarily unavailable'))) {
          console.log('遇到资源错误,重试操作...');
          return withRetry(fn, retries - 1);
        }
        throw err;
      }
    }
    
    // 使用重试包裹关键操作
    await withRetry(async () => {
      await page.goto('目标页面URL', { timeout: 30000 });
    });
    
  • 确保任务串行执行
    即便设置了每20分钟执行一次,也要保证前一次任务完全结束后再启动下一次。如果前一次任务因资源泄漏未彻底清理,新任务启动会加剧资源占用。可以用Redis实现互斥锁,确保同一时间只有一个爬虫任务在运行:

    const redis = require('redis');
    const client = redis.createClient(process.env.REDIS_URL);
    
    async function acquireLock() {
      const lockKey = 'crawler-running-lock';
      // 设置30秒过期锁,防止任务崩溃后锁无法释放
      const result = await client.set(lockKey, 'active', { EX: 30, NX: true });
      return result === 'OK';
    }
    
    async function runCrawler() {
      const hasLock = await acquireLock();
      if (!hasLock) {
        console.log('已有爬虫任务在运行,跳过本次执行');
        return;
      }
      try {
        // 爬虫逻辑代码
      } finally {
        await client.del('crawler-running-lock'); // 释放锁
        if (browser) await browser.close();
      }
    }
    
  • 优化爬虫资源占用
    执行heroku logs --tail查看实时日志,关注是否有R14内存超限提示。如果频繁出现,要么升级到Basic计划(1GB内存),要么优化爬虫逻辑:

    // 禁用图片、视频、字体加载,减少资源消耗
    await page.route('**/*', (route) => {
      const resourceType = route.request().resourceType();
      if (['image', 'video', 'font'].includes(resourceType)) {
        route.abort();
      } else {
        route.continue();
      }
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:27:29