1

有一个生产系统已经运行了很多年,最初是作为 PHP 应用程序,然后是与 Rails 的混合体,现在完全在 Rails 中。目前尚不清楚它已经存在了多长时间。最古老的 git commit 是从 5 年前开始的。

目标是不惜一切代价保持系统运行。只要没有中断,我们使用什么代码都没有关系。目前它是 Rails 版本3.2.33

如果我们不升级任何宝石,我们就有可能变得过时且无法部署。如果我们升级,我们将需要对代码进行更改,从而导致潜在的错误蔓延。我们不仅面临代码腐烂,而且还面临由于 AWS 中断而导致的停机。

确保万无一失的第一步是什么?我花了几个月的时间编写黄瓜(集成)测试,但很难涵盖所有边缘情况。该应用程序已经运行了很长时间,以至于大多数错误都已修复,并且几乎没有新的异常。测试从一开始就不是优先事项,因此大多数代码都没有记录。

4

3 回答 3

4

老实说,我发现 Ruby on Rails 并不适合这种应用程序。Ruby 和 Rails 都有一个非常激进的发布计划,Rails 尤其不怕放弃向后兼容性。Rails 非常适合敏捷开发,其中事物总是在变化,但以长期稳定性为代价。

我假设您的应用程序足够大,以至于您不想切换到其他任何东西。例如, Sinatra并没有太大变化,并且将是一个更稳定的选择。

如果您坚持使用 Rails,我建议您摆脱尽可能多的 gem 依赖项。总是存在不再开发它们或者它们可能引入错误或漏洞的危险。

此外,尽可能地支持 PORO(普通的旧 Ruby 对象)而不是依赖于 Rails 的代码是一个好主意。它通常需要更多的工作,但你最终会得到更稳定和可重用的代码。

我意识到这可能比你想在这样的应用程序中投入更多的工作,但这是我最好的建议。

于 2015-10-30T10:43:05.793 回答
1

第一步是为 gem 文件中使用的所有 gem 放置特定的 gem 版本。

例如

 gem 'rspec-rails'

可能变成

 gem 'rspec-rails', '2.14.1'

您可以通过查看 Gemfile.lock 来确定当前正在使用哪些版本,例如,Gemfile.lock 中的这一行显示为 rspec 选择的版本:

rspec (2.14.1)

即使 Gemfile 没有版本,例如

gem chronic

Gemfile具有使用的版本,例如

chronic (0.10.2)

如果我们不升级任何宝石,我们就有可能变得过时且无法部署。如果我们升级,我们将需要对代码进行更改,从而导致潜在的错误蔓延。

是的,这就是你的困境。没有任何魔法,您必须选择您想要解决的这两个优先事项中的哪一个。正如 aNoble 所指出的,RoR 不是一个可以“原地不动”的框架。组成大多数应用程序的 gem 的不断变化意味着 RoR 应用程序不能很好地老化。

您应该向项目所有者解释并重复,重复,重复。通常这是“接受”的那种原则——但不是真的——因为同样的问题继续被问到“尽管如此,我如何升级它,我如何确保没有任何变化或中断,等等。”

如果应用程序将在几个月内退役,那没问题。如果没有真正的计划来终止应用程序并且它将继续成为业务的重要组成部分,那么您只需要使用资源来维护它。在 RoR 土地上没有免费的午餐。

于 2015-10-30T10:52:00.483 回答
1

编写许多测试是关键的第一步,很高兴看到这一点。检查您的语句覆盖率,看看您是否缺少对重要代码区域的测试,并确保您有涵盖关键序列的集成测试。这个想法是修改您的测试以降低更改将导致用户可见故障的风险。

现在在某些系统上设置连续测试。

设置您的 Gemfile 和 .ruby-version 以便您可以具体控制加载所有内容的版本。这不会自动更新 - 但它确保您可以控制更新的内容。检查 Gemfile 和 Gemfile.lock。

此时可以慢慢增加版本号。不要跳过很多版本号 - 通常最好慢慢升级,这样您就可以看到弃用警告。修复那些,冲洗,重复。

将您的(输入)验证器修改为挑剔的白名单(“它必须是这种形式,否则我不会接受它”)。如果您可以防止不良数据进入您的系统,它就更有可能正常工作并且通常更难受到攻击。

为了安全起见,请考虑添加安全标头,并将 CSP 设置为尽可能强。

开始添加一些静态分析器。Rubocop 和 Brakeman 非常有用。您可能必须将 Rubocop 配置为只抱怨一些事情,然后慢慢增加他们报告的内容。将所有检查添加到默认的“rake”命令中,这样您只需键入“rake”即可运行静态分析器和测试套件。

无论您使用什么框架,都没有魔法。人们会犯错误,而假装是没有帮助的。

您可能会将CII 最佳实践徽章项目作为一个有用的示例。它使用 RoR,我领导。特别是,请参阅: * CONTRIBUTING *安全信息(保证案例)

来自 CONTRIBUTING:“一般来说,我们会尽量主动检测和消除错误和漏洞,并在它们发生时减少它们的影响。我们使用防御性设计和编码风格来减少错误的可能性,各种尝试及早发现错误的工具,以及覆盖率很高的自动测试套件。”

于 2017-03-09T22:18:45.557 回答