时隔一年半,期待已久的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如下:
然后执行 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里面也自然没有这个启动模式了。
解决办法是使用systemd、monit、pm2这些第三方的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,貌似也不会变?不清楚是不是我理解还不到位。
总体来说,因为项目比较小,这次升级还是比较顺利的,但好像也没带来什么特别的优势。所以,对于想升级的朋友,可以参考一下。