Azure容器应用中Sidekiq连远程Redis静默终止问题排查
问题详情
版本信息
- Ruby版本:3.2.6
- Rails版本:7.2.2
- Sidekiq版本:7.3.5
问题描述
在Azure容器应用中使用远程Redis URL时,Sidekiq输出初始化日志后立即静默终止,未记录任何错误。通过Rails控制台已确认Redis连接正常,使用本地Redis实例时无此问题。
预期行为
Sidekiq应启动并持续运行,处理后台任务。
实际行为
Sidekiq在输出以下日志后立即终止:
2025-01-02T13:00:30.663Z pid=27 tid=4k7 INFO: Booted Rails 7.2.2 application in staging environment 2025-01-02T13:00:30.663Z pid=27 tid=4k7 INFO: Running in ruby 3.2.6 (2024-10-30 revision 63aeb018eb) [x86_64-linux] 2025-01-02T13:00:30.663Z pid=27 tid=4k7 INFO: See LICENSE and the LGPL-3.0 for licensing details. 2025-01-02T13:00:30.663Z pid=27 tid=4k7 INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org 2025-01-02T18:18:36.577Z pid=27 tid=4k7 INFO: Sidekiq 7.3.5 connecting to Redis with options {:size=>10, :pool_name=>"internal", :url=>"redis://:REDACTED@project-redis.redis.cache.windows.net:6379"}
入口点代码
bundle exec rails s -d echo "Sidekiq should start here" bundle exec sidekiq -C /myapp/config/sidekiq.yml
sidekiq.rb配置
Sidekiq.configure_server do |config| config.redis = { url: ENV['REDIS_URL'] || 'redis://localhost:6379' } end Sidekiq.configure_client do |config| config.redis = { url: ENV['REDIS_URL'] || 'redis://localhost:6379' } end
sidekiq.yml配置
# Sample configuration file for Sidekiq. # Options here can still be overridden by cmd line args. # Place this file at config/sidekiq.yml and Sidekiq will # pick it up automatically. --- :verbose: false :concurrency: 10 :timeout: 25 :queues: - critical - default - low - exports - mailer production: :concurrency: 25 staging: :concurrency: 25 development: :concurrency: 15
更新信息
尝试在Sidekiq中使用at_exit方法获取调试信息,输出如下:
Error Information: Exit Status: 1 Error Class: SystemExit Error Message: exit Backtrace: /usr/local/bundle/gems/bundler-2.3.6/lib/bundler/friendly_errors.rb:110:in `exit' /usr/local/bundle/gems/bundler-2.3.6/lib/bundler/friendly_errors.rb:110:in `rescue in with_friendly_errors' /usr/local/bundle/gems/bundler-2.3.6/lib/bundler/friendly_errors.rb:101:in `with_friendly_errors' /usr/local/bundle/gems/bundler-2.3.6/exe/bundle:36:in `<top (required)>' /usr/local/bundle/bin/bundle:25:in `load' /usr/local/bundle/bin/bundle:25:in `<main>'
看起来是Bundler终止了Sidekiq进程。
疑问
- 如何理解当前状况或定位错误?
- 远程Redis存在已知问题吗?
- 此问题是否与Azure容器应用相关?
- 如何启用更详细的日志进行调试?
解决方案与分析
1. 错误定位与状况理解
从at_exit回溯信息来看,Bundler的友好错误处理机制捕获了Sidekiq启动时的异常,直接调用exit终止了进程,但未暴露原始异常。可以通过以下方式定位根源:
- 绕过Bundler直接执行Sidekiq,获取原始异常:
bundle exec ruby -r sidekiq -e 'Sidekiq::CLI.instance.run(["-C", "/myapp/config/sidekiq.yml"])' - 检查入口点脚本逻辑:
rails s -d后台启动Rails后,容器是否将Sidekiq视为主进程?若Rails后台启动失败,可能间接影响Sidekiq执行。
2. 远程Redis相关排查
Azure Redis与Sidekiq无已知兼容性问题,但需注意以下细节:
- Azure Redis默认强制SSL连接,当前Redis URL使用
redis://而非rediss://,需确认是否匹配Azure Redis的SSL配置,若启用SSL必须改用rediss://开头的URL。 - 检查Azure Redis的连接配额:Sidekiq默认连接池大小为10,加上Rails客户端连接数,需确保未超出Redis实例的最大连接限制。
- 确认容器应用IP在Azure Redis防火墙允许列表内(虽然控制台能连接,但需排除连接池配置差异导致的问题)。
3. Azure容器应用关联排查
存在一定关联可能性:
- 容器环境要求主进程持续运行,若Sidekiq异常退出,容器会触发重启,需确认容器日志采集是否完整,是否有遗漏的错误输出。
- 验证环境变量传递:确保
REDIS_URL在Sidekiq进程中被正确读取,可在启动前添加echo $REDIS_URL验证。 - 尝试将Rails与Sidekiq拆分为独立容器部署,避免单容器多进程的管理冲突。
4. 启用详细日志调试
- 修改
sidekiq.yml,将:verbose: false改为:verbose: true,开启基础详细日志。 - 启动时添加调试级日志参数:
bundle exec sidekiq -C /myapp/config/sidekiq.yml --log-level debug - 禁用Bundler友好错误,强制显示原始异常:
BUNDLE_FRIENDLY_ERRORS=false bundle exec sidekiq -C /myapp/config/sidekiq.yml - 添加自定义错误捕获,将异常写入文件:
在sidekiq.rb中追加:Sidekiq.configure_server do |config| config.error_handlers << ->(ex, ctx_hash) do File.open('/myapp/log/sidekiq_errors.log', 'a') do |f| f.puts "#{Time.now} - #{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}" end end end
额外排查点
- 执行
bundle check确认所有依赖gem已正确安装。 - 更新Bundler至最新稳定版(当前使用的2.3.6版本较旧),执行
gem install bundler:2.5.9(替换为最新版)后重新bundle install。 - 检查容器内系统时间、时区是否与Azure Redis实例匹配,避免超时问题。
内容的提问来源于stack exchange,提问作者Mo'men Mohamed Hamdy
相关产品推荐
相关产品推荐

