通过模板启用 YJIT 无效

你好,

我运行的是自托管的 Discourse 安装版(2026.5.0-latest)。今天我尝试启用 YJIT。我在 containers/app.yml 中添加了 "templates/enable-ruby-yjit.yml" 并重新构建了应用。

重新构建完成后,发生了一些有趣的事情。在 Docker 容器内,我运行了 env | grep RUBY_YJIT_ENABLE,得到了 RUBY_YJIT_ENABLE=1。到目前为止一切正常。但随后我运行了 sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION',结果却是:

YJIT enabled: false

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [x86_64-linux] 

尽管添加了 enable-ruby-yjit.yml 模板,YJIT 仍未启用。接着,当我运行 sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"' 时,得到的是 GlobalSetting.yjit_enabled= —— 一个空值!

总之,在进一步折腾后,我最终通过在 containers/app.yml 中添加以下内容成功启用了 YJIT:

env:
  DISCOURSE_YJIT_ENABLED: true

我确信某处存在一个 bug(GlobalSetting.yjit_enabled 绝不应该返回 nil),但设置环境变量确实生效了。希望有人通过 Google 搜索到这个问题时能发现这个主题。

1 个赞

这难道不是误诊吗?你检查的是一个新启动的 Ruby 进程的 ENV,而不是实际运行 Web 服务器的那个进程。

如果你检查 Pitchfork 主进程的 /proc/<pid>/environ,你会在那里看到 YJIT 环境变量。

root@raspberrypi5:/var/discourse# cat /proc/3331660/environ | tr '\0' '\n' | grep -i yjit
RUBY_YJIT_ENABLE=1

查看环境变量是否存在并不能说明 Ruby 当前是否启用了 YJIT。在本例中,虽然该环境变量已设置,但另有其他因素覆盖了 Rails 用于在启动时启用(或禁用)YJIT 的变量。除此之外,没有其他理由能解释为何 GlobalSetting.yjit_enabled= 即使在新的 Rails 实例中也返回 nil。同样,也没有理由认为 YJIT 在新启动的 Rails 实例中会被禁用。

在将 DISCOURSE_YJIT_ENABLED 环境变量添加到我的 containers/app.yml 后:

  1. 执行 sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' 返回 YJIT enabled: true
  2. 服务器的内存使用量终于略有上升。
  3. 我的论坛速度明显提升。

复现我的发现应该很容易。只需添加模板并查看即可。