美文网首页Ruby & RailsRuby on RailsRuby
Rails 5 生产环境默认关闭 autoloading

Rails 5 生产环境默认关闭 autoloading

作者: 老码农不上班 | 来源:发表于2016-09-12 18:25 被阅读742次

    开发 payslip 时,有一个自定义模块放在 lib/payslip目录下,在 config/application.rb目录下添加了config.autoload_paths << Rails.root.join('lib'),开发环境中跑的好好的,但部署之后,却遇到模块没加载的错误。然后就翻了一下相关文档以及博客。
    默认你已经了解自动加载,如果不熟悉的话,请在 Rails 指南中查阅对应文档 Autoloading and Reloading Constants

    Eagerload paths

    Autoloading 是线程不安全,所以我们要确保 Rails 应用跑起来时所有的常量(Autoloading and Reloading Constants)都加载进来。在使用之前加载所有常量的概念就是 Eagerload ,反之就是 Autoloading, Autoloading就是需要使用时才把常量加载。譬如当一个 class 被需要且没有在内存中找到时,Rails 就会在 autoloading paths路径中查找并加载。
    eager_load_paths包含一些列目录,当 Rails 应用在在生产环境中启动,同时会把列在eager_load_paths中所列的文件或者文件目录加载。
    例如:

    # config/application.rb
    
    config.eager_load_paths << Rails.root.join('lib')
    

    Rails 5 生产环境默认不允许 autoloading

    就像今天我遇到的错误一下,虽在 config.autoload_paths中把lib文件目录添加了,但是在生产环境中仍然找不到需要用的模块。原因就在于此。
    通过这个 commit可得知,Rails 应用在生产环境不会执行 autoloading
    在生产环境中,Rails 会从 eager_load_paths中加载所有常量(文件),如果找不到常量,再也不会通过 autoload_paths继续寻找。
    这是比较大的一个改动,如果之前的项目使用了 autoload_paths,升级到 Rails 5 时需要作出对应的改动。譬如之前在 config/application.rb中如果 config.autoload_paths << Rails.root.join('lib'),则你需要改为 config.eager_load_paths << Rails.root.join('lib')
    另外,在极少数情况下,如果Rails 5 项目很有必要继续沿用 autoloading,可通过把 enable_dependency_loading 设置为 true。但是不推荐,我试过通过这样的方式,发现在生产环境中,访问页面,整个性能都慢下来了。

    # config/application.rb
    
    config.enable_dependency_loading = true
    config.autoload_paths << Rails.root.join('lib')
    

    推荐阅读:
    confusing about autoload_paths vs eager_load_paths in rails 4谈到了 autoload-paths 导致页面访问慢的问题。
    In production, custom autoload_paths are not respected

    相关文章

      网友评论

      本文标题:Rails 5 生产环境默认关闭 autoloading

      本文链接:https://www.haomeiwen.com/subject/adgpettx.html