Rails应用通过Sidekiq调用Chromedriver时连接失败问题排查
Rails Sidekiq任务无法连接chromedriver的解决方案
以下是针对Ubuntu 22.04环境下,Rails应用通过Sidekiq执行任务时无法连接/usr/bin/chromedriver问题的排查和解决步骤:
1. 强制指定chromedriver路径并启用调试日志
在Selenium初始化代码中明确指定chromedriver路径,同时开启日志输出,排查启动过程中的错误:
options = Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless=new') # 适配新版本Chrome的无头模式 options.add_argument('--no-sandbox') # 规避Ubuntu下的权限限制 options.add_argument('--disable-dev-shm-usage') # 解决临时空间不足问题 driver = Selenium::WebDriver.for( :chrome, options: options, executable_path: '/usr/bin/chromedriver', driver_opts: { log_path: Rails.root.join('log/chromedriver.log').to_s, verbose: true } )
执行Sidekiq任务后,查看log/chromedriver.log,定位chromedriver启动失败的具体原因(如依赖缺失、权限问题等)。
2. 同步Sidekiq运行环境变量
若Sidekiq通过systemd等服务管理器启动,其环境变量可能与终端/控制台不一致:
- 检查Sidekiq启动脚本或systemd服务文件,确保
PATH包含/usr/bin; - 若使用systemd,在服务文件中添加环境变量配置:
[Service] # 其他配置... Environment="PATH=/usr/bin:/usr/local/bin" Environment="HOME=/home/your-rails-user" # 确保chromedriver可写入临时文件 - 重启Sidekiq服务后测试:
sudo systemctl restart sidekiq
3. 排查进程权限与系统限制
- 确认Sidekiq运行用户对
/usr/bin/chromedriver有执行权限:ls -l /usr/bin/chromedriver # 需保证输出的权限位包含其他用户执行权限(即末尾有x) - 检查AppArmor是否限制了chromedriver的网络操作:
若存在deny记录,可临时禁用AppArmor测试:sudo aa-status
测试正常后,再调整AppArmor规则允许chromedriver的网络连接。sudo systemctl stop apparmor && sudo systemctl disable apparmor
4. 手动测试chromedriver启动与连接
在Sidekiq任务中添加手动测试代码,确认chromedriver是否能正常启动并接受连接:
require 'net/http' class YourScraperWorker include Sidekiq::Worker def perform test_chromedriver_connection # 原有的抓取逻辑 end private def test_chromedriver_connection chromedriver_pid = spawn('/usr/bin/chromedriver --port=9515', out: '/dev/null', err: '/dev/null') sleep 2 # 等待启动完成 begin response = Net::HTTP.get(URI('http://127.0.0.1:9515/status')) Rails.logger.info("Chromedriver status: #{response}") rescue Errno::ECONNREFUSED => e Rails.logger.error("连接chromedriver失败: #{e.message}") Rails.logger.info("chromedriver进程 #{chromedriver_pid} 是否存活: #{Process.alive?(chromedriver_pid)}") ensure Process.kill('TERM', chromedriver_pid) if Process.alive?(chromedriver_pid) end end end
通过日志判断是chromedriver启动失败,还是启动后无法建立连接,进一步缩小排查范围。
内容的提问来源于stack exchange,提问作者brunotiago
相关产品推荐
相关产品推荐

