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.
相关产品推荐
相关产品推荐

