为何Ruby on Rails的Spring Preloader不应部署到生产环境?
先得明确,Spring从设计之初就是给开发环境量身定做的,压根没考虑生产场景——这是核心原因,具体来说有这几点:
内存泄漏风险极高:Spring的核心是在进程里预加载应用,开发时频繁改代码、重载的过程中,它的资源回收机制并不完善,很容易留下内存泄漏的隐患。生产环境的服务是长期运行的,泄漏的内存会不断积累,最终拖垮整个应用,而开发时我们频繁重启进程,根本不会遇到这个问题。
和生产环境部署机制冲突:生产环境一般用Puma、Unicorn这类多进程/多线程服务器,它们本身有成熟的进程管理和应用加载策略。Spring的预加载是通过父进程加载应用再fork子进程的方式实现的,这会打乱生产服务器的资源隔离逻辑,比如导致数据库连接池被错误复用、进程间状态意外共享,引发各种难以排查的问题。
没有生产级的稳定性保障:Spring完全没做生产环境的稳定性优化,比如错误隔离、资源监控、故障恢复这些生产必备的能力一概没有。官方也明确不支持在生产环境使用它,出了问题连官方文档都找不到排查方向。
破坏生产环境的代码一致性:开发时Spring会自动重载修改后的代码,方便我们快速验证,但生产环境需要的是固定版本的稳定代码。Spring的重载机制在生产环境可能会导致意外的代码更新,或者缓存旧代码,引发线上服务的行为不一致,这对生产来说是致命的。
反而拖慢生产性能:生产环境的应用启动是一次性的(部署阶段),之后会长期运行。Spring的预加载会额外增加启动开销,还得维护一个闲置的预加载进程,纯粹浪费内存资源——生产环境不需要频繁启动
rails console、generate这类命令,Spring的加速优势完全用不上,反而成了负担。
内容的提问来源于stack exchange,提问作者Arjun Dubey

