Rails 7部署AWS Elastic Beanstalk时Puma启动卡在rdb无法运行
将现有Rails 5代码库升级至Rails 7版本后,代码在本地开发环境、独立EC2实例上运行均正常,部署到Elastic Beanstalk后,服务启动进程卡在rdb调试阶段无法完成启动,相关运行日志如下:
Puma starting in single mode... Jun 21 11:25:08 ip-172-31-23-186 web: * Puma version: 5.6.4 (ruby 2.7.6-p219) ("Birdie's Version") Jun 21 11:25:08 ip-172-31-23-186 web: * Min threads: 5 Jun 21 11:25:08 ip-172-31-23-186 web: * Max threads: 5 Jun 21 11:25:08 ip-172-31-23-186 web: * Environment: development Jun 21 11:25:08 ip-172-31-23-186 web: * PID: 22775 Jun 21 11:25:11 ip-172-31-23-186 web: /opt/rubies/ruby-2.7.6/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError Jun 21 11:25:11 ip-172-31-23-186 web: /var/app/current/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.3/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here Jun 21 11:25:11 ip-172-31-23-186 web: /opt/rubies/ruby-2.7.6/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE Jun 21 11:25:11 ip-172-31-23-186 web: /var/app/current/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.3/lib/net/protocol.rb:208: warning: previous definition of BUFSIZE was here Jun 21 11:25:11 ip-172-31-23-186 web: /opt/rubies/ruby-2.7.6/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket Jun 21 11:25:11 ip-172-31-23-186 web: /var/app/current/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.3/lib/net/protocol.rb:504: warning: previous definition of Socket was here Jun 21 11:25:13 ip-172-31-23-186 web: /opt/rubies/ruby-2.7.6/lib/ruby/2.7.0/x86_64-linux/continuation.so: warning: callcc is obsolete; use Fiber instead Jun 21 11:25:15 ip-172-31-23-186 web: (rdb:1) Debug.rb Jun 21 11:25:15 ip-172-31-23-186 web: Emacs support available. Jun 21 11:25:15 ip-172-31-23-186 web: /opt/rubies/ruby-2.7.6/lib/ruby/site_ruby/2.7.0/bundler/runtime.rb:47: next unless (dep.groups & groups).any? && dep.should_include? Jun 21 11:25:25 ip-172-31-23-186 web: (rdb:1) /var/app/current/config/application.rb:45:module AppName
日志中AppName为实际应用名称。本地直接执行puma命令启动无法复现故障,问题仅出现在Elastic Beanstalk环境。
本地环境
- ruby = 2.7.6
- rails = 7.0.3
Elastic Beanstalk环境
- AMI = Amazon Linux 2
- Platform = Ruby 2.7
从日志可定位两个核心问题:服务错误以development环境启动、无交互终端下rdb调试器被触发阻塞启动流程,按以下步骤修复即可:
修正EB运行环境
进入Elastic Beanstalk环境配置-软件设置,添加两个环境变量:RAILS_ENV=productionRACK_ENV=production
EB的Ruby平台默认未配置环境变量时会以development模式启动,开发环境会自动加载所有调试类gem,且线上环境本身就不应该跑开发模式,这是本地/独立EC2正常、EB异常的核心差异点。
限制调试gem的加载范围
打开项目根目录Gemfile,确认所有调试相关gem(包括rdb、debug、pry、byebug等)全部放在:development, :test分组下,禁止生产环境加载,参考配置:group :development, :test do gem 'rdb' gem 'debug' gem 'pry' gem 'byebug' end修改后执行
bundle install,将更新后的Gemfile.lock提交到代码仓库。清理残留调试断点
全局搜索项目代码,重点检查config/application.rb第45行附近,删除所有残留的debugger、binding.rdb、binding.pry类调试触发语句,这类语句在开发环境下会自动唤起调试器。可选:修复net-protocol常量重复警告
日志中的常量重复警告是Ruby 2.7自带标准库与bundler安装的新版net-protocol gem版本冲突导致,不影响服务运行,要消除警告可在Gemfile中添加配置锁定版本:gem 'net-protocol', '~> 0.1.3' if RUBY_VERSION < '3.0'执行
bundle update net-protocol后提交变更即可。
内容的提问来源于stack exchange,提问作者Kavii Suri

