Rails Rails 6.1 升级记录

chriszou · 2020年12月15日 · 最后由 xinyuewaisong 回复于 2021年01月02日 · 2401 次阅读
本帖已被管理员设置为精华贴

时隔一年半,期待已久的 Rails 6.1 终于发布了。趁着双休,给 GeekWeibo 从 Rails6.0 升级到了 6.1。 升级主要有三步。

一、升级 Gemfile 里面各个 gem 的版本

为了避免一些 gem 版本的不兼容,我先本地gem install rails把系统的 rails 版本升级到 6.1。然后使用 rails new demo61 创建了一个新 app 叫 demo61。接着对比 demo61/Gemfile 和 geekweibo/Gemfile 里面各个 gem 的版本号,相应的升级一下版本号。主要 diff 如下: NvOr8T

然后执行 bundle update

二、执行 rails app:update

前几天才知道原来还有 rails app:update这个命令,用于 app 升级。执行一下,按照提示,相应的覆盖或忽略一些文件更新。执行完了之后,很多 bin 文件和 config 文件都更新了。同时会生成两个新的 active_storage 的 migration file。一个是给 active_storage_blobs table 新增了一个 service_name column:

# This migration comes from active_storage (originally 20190112182829)
class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
  def up
    unless column_exists?(:active_storage_blobs, :service_name)
      add_column :active_storage_blobs, :service_name, :string

      if configured_service = ActiveStorage::Blob.service.name
        ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)
      end

      change_column :active_storage_blobs, :service_name, :string, null: false
    end
  end

  def down
    remove_column :active_storage_blobs, :service_name
  end
end

另外一个是新增了一个active_storage_variant_records table

# This migration comes from active_storage (originally 20191206030411)
class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
  def change
    create_table :active_storage_variant_records do |t|
      t.belongs_to :blob, null: false, index: false, type: :uuid
      t.string :variation_digest, null: false

      t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true
      t.foreign_key :active_storage_blobs, column: :blob_id
    end
  end
end

接着执行 rails db:migrate,一切正常。

三、使用 systemd 管理 puma 进程

我的项目是使用 capistrano 来部署的。执行完前面的两个步骤,本地试运行,解决掉一个 gem 的兼容性问题(后面会提到)之后。执行cap production deploy之后,提示没有 cap production puma:restart这个 task。一番 google 之后,发现原来是 puma 5 把 daemon 启动模式去掉了。相应的 capistrano3-puma 5.0 之后的版本,默认的 task 里面也自然没有这个启动模式了。 解决办法是使用systemdmonitpm2这些第三方的 process monitor/manager。我因为不想折腾,所以采用 linux(或者说 ubuntu)自带的 systemd。

在 Capfile 里面新增一行

# 在install_plugin Capistrano::Puma 之后
install_plugin Capistrano::Puma::Systemd

然后执行

cap puma:systemd:config    # 会生成一个systemd unit文件,并上传到服务器的/etc/systemd/system/文件夹下面。
cap puma:systemd:enable    # Enable上一步上传的service

然后再执行 cap production puma:restart,这个命令会在服务器上面会执行sudo systemctl restart puma这时候提示报错了,说 systemd 的 service unit 里面,ExecStart 的命令格式有问题。我查看了一下,发现生成的 unit 文件里面,ExecStart 这一行的内容是

ExecStart=~/.rvm/bin/rvm default do bundle exec puma -C /your/deploy/path/geekweibo/shared/puma.rb

我猜测是~/这个地方出错了。改成绝对路径

ExecStart=/home/username/.rvm/bin/rvm default do bundle exec puma -C /your/deploy/path/geekweibo/shared/puma.rb

然后在服务器上面执行 sudo systemctl daemon-reload,因为我们修改了 unit 文件,需要 reload 一下 systemd daemon 生效。

回到开发机,再次执行cap production puma:restart,果然就可以了。我猜测之所以 ~/这种写法会有问题,是因为我没有指定 puma 的 user。

遇到的问题

不少朋友说升级 6.1 之后,遇到很多 gem 不兼容的情况。可能是因为我这个项目比较小,我这次升级,只遇到一个 gem 不兼容。那就是skylight-ruby gem(一个 APM 服务)。报了一个

NoMethodError (undefined method `instrument' for #<ActionView::TemplateRenderer:0x00007f9d9cc61ee8>)

这样的错。这个 gem 的Github issues里面也有不少人反映这个问题。据作者说,gem 新版 beta 里面已经解决了,不过我不想采坑,所以没上 beta,只是按照他们的说明,用了一个 workaround,在 config/application.rb 里面加一行

config.skylight.probes -= %w[action_view]

解决了问题。

升级以后,有了哪些好处呢?

好像没发现。Rails 6.1 很多新增功能是针对 multiple DB 的,对我好像没什么影响。我主要是冲着 strict loading 和 activestorage 的 permanent url 来的。其中 strict loading,在另外的一个小 app 里面开了 strict loading by default,结果带来一些问题,于是又禁用了。而 activestorage 的 permanent url,除了方法名使用 url 代替 service_url,其他好像也没发现什么区别。我原来使用 service_url 获取到的 url,貌似也不会变?不清楚是不是我理解还不到位。

总体来说,因为项目比较小,这次升级还是比较顺利的,但好像也没带来什么特别的优势。所以,对于想升级的朋友,可以参考一下。

其它好说看到 webpacker 心里一惊赶紧去找升级文档。

Rei 回复

是说 webpacker 升级到了 5.x 吗?[捂脸] 无脑升级以后,看起来没问题😉

chriszou 回复

暂时没遇到问题,主要都忘了 webpack 怎么设置了,如果要改配置就很费时间 😅

Delegated Types 👍

另外不尝试一下 capistrano-foreman 么?

xinyifly 回复

惭愧,虽然听说,但一直没用过 foreman 呢,所以自然也没了解过 capistrano-foreman😅

chriszou 回复

可以尝试一下。我开发环境一堆 worker,用 foreman 一键就全启动了。生产环境用 capistrano-foreman 可以给所有的 worker 生成 systemd 服务。

sidekiq6 部署也不支持 daemon 了 看来 cap 的插件都的多多少少动一下了

huacnlee 将本帖设为了精华贴。 12月17日 23:23

另外,我司内部一个比较复杂的后台系统也升级到 Rails 6.1 了,比较顺利

huacnlee 回复

学习了!👍 最近也计划用 PG FTS 代替 ElasticSearch

6666,这么好

  1. 需要添加部署用户到 sudo,并配置无密码 sudo 运行
  2. 生成 puma.rb 本地运行 $ cap production puma:systemd:config puma:systemd:enable
  3. 生成的 puma.rb 如果需要修改 修改后 服务器端需要重启 systemd $ sudo systemctl daemon-reload $ sudo /bin/systemctl start puma
需要 登录 后方可回复, 如果你还没有账号请 注册新账号