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

Heroku上Sidekiq任务中Selenium/Watir无法连接Chromedriver问题

问题解决指南

一、解决Sidekiq中Chrome/Chromedriver连接失败问题

1. 检查并修正环境变量PATH

一次性dyno能正常运行,说明Sidekiq dyno的PATH可能未包含chrome-for-testing的可执行文件路径。在Heroku配置中添加环境变量:

PATH=/app/.chrome-for-testing/chromedriver-linux64:/app/.chrome-for-testing/chrome-linux64:$PATH

添加后重启Sidekiq dyno,无需在代码中显式指定路径,直接使用默认配置即可:

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')

browser = Watir::Browser.new :chrome, options: options

2. 验证Chromedriver执行权限

若PATH配置后仍失败,检查Chromedriver文件权限。可在Sidekiq任务启动前添加权限修复代码:

chromedriver_path = '/app/.chrome-for-testing/chromedriver-linux64/chromedriver'
File.chmod(0755, chromedriver_path) if File.exist?(chromedriver_path)

3. 启用Chromedriver日志排查

添加日志参数,查看启动失败的具体原因:

service = Selenium::WebDriver::Service.chrome(
  path: '/app/.chrome-for-testing/chromedriver-linux64/chromedriver',
  args: ['--verbose', '--log-path=/tmp/chromedriver.log']
)
# 后续options和browser初始化不变

执行任务后,通过heroku run cat /tmp/chromedriver.log查看日志,定位是启动失败、端口冲突还是资源不足。

4. 调整Chrome启动参数避免端口冲突

尝试指定调试端口,避免默认端口9515被占用:

options.add_argument('--remote-debugging-port=9516')

二、解决Heroku上爬虫内存膨胀问题

1. 降级Chrome-for-testing版本

Chrome 129版本可能存在内存占用过高的问题,尝试降级到稳定的旧版本(如128)。在Heroku配置中设置:

CHROME_VERSION=128.0.6613.119

重新部署后测试内存占用情况。

2. 修复代码中的资源泄漏

确保每次爬取完成后彻底释放浏览器资源:

begin
  # 爬虫逻辑
ensure
  browser.quit if browser.present? # 必须调用quit,而非仅close,确保销毁所有Chrome进程
end

避免因未关闭浏览器导致的内存泄漏,本地环境可能自动回收进程,但Heroku dyno环境不会。

3. 优化Chrome启动参数减少内存占用

添加以下参数降低Chrome内存消耗:

options.add_argument('--single-process') # 单进程模式,仅headless下可用
options.add_argument('--disable-extensions')
options.add_argument('--disable-plugins')
options.add_argument('--low-memory-mode')
options.add_argument('--disable-features=VizDisplayCompositor')
options.add_argument('--window-size=1920,1080') # 固定窗口大小,避免动态分配内存

4. 分批处理任务

将大规模爬虫任务拆分为多个小批次,每完成一批就重启浏览器,释放内存:

batch_size = 10
urls.each_slice(batch_size) do |batch|
  browser = Watir::Browser.new :chrome, options: options
  begin
    batch.each { |url| crawl(url) }
  ensure
    browser.quit
  end
end

5. 利用Heroku工具监控内存

  • 使用heroku logs --tail查看进程终止前的内存告警日志
  • 临时升级dyno规格(如heroku ps:resize worker=standard-2x),测试是否能完成任务,判断是内存不足还是泄漏问题

内容的提问来源于stack exchange,提问作者Jeremy R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:31:01