有哪些好的策略可允许已部署的应用程序可热修复?
在理想的情况下,我们的开发流程将是完美的,从而导致常规发行版经过了全面的测试,因此无需"修复"正在运行的应用程序。
但是,不幸的是,我们生活在现实世界中,有时错误会从我们身边溜走,直到我们已经忙于编写下一个版本的代码时才抬起丑陋的脑袋。该错误需要立即修复。不作为下一个计划发行的一部分。今晚交通不畅时,还不是晚上。现在。
我们如何处理这种需求?它确实会与良好的设计规范背道而驰,例如将代码重构为漂亮的离散类库。
在生产服务器上手动编辑标记和存储过程可能会导致灾难,但也可以避免灾难。
应用程序设计和部署技术在维护需求和良好编码实践之间取得平衡的最佳策略是什么?
解决方案
[即使我们在发布前进行了大量测试,]我们的工作是这样的:
我们的SVN如下所示:
/repo/trunk/ /repo/tags/1.1 /repo/tags/1.2 /repo/tags/1.3
现在,无论何时发布,我们都会创建一个标签,最终在生产中签出该标签。在进行生产之前,我们要进行分阶段,即[较少的服务器,但]与生产几乎相同。
创建"标签"的原因包括生产中代码中应用程序的某些设置与" trunk"略有不同(例如,没有通过电子邮件发送但记录了错误),因此创建标签并提交这些更改是有意义的。然后在生产集群上签出。
现在,无论何时需要修复问题,我们都先在标签/ x中修复它,然后从标签中" svn更新"就可以了。有时,我们会进行分期,但有些问题(例如拼写等次要/琐碎的修正)会绕过分期。
唯一要记住的是将所有来自" tags / x"的补丁应用到" trunk"。
如果我们有一台以上的服务器,Capistrano对运行所有这些操作非常有帮助。
一种策略是对不同组件大量使用声明式外部配置文件。
这样的例子:
- 通过类似IBatis / IBatis.NET的工具进行数据库访问/对象关系映射
- 通过JLog / NLog之类的工具进行记录
- 通过诸如Spring / Spring.NET之类的工具进行依赖注入
这样,我们通常可以将关键组件分离为离散的部分,无需重新编译就可以对正在运行的应用程序进行热修复,并无缝使用源代码控制(尤其是与通常需要手动进行源代码控制的存储过程相比)。
我们将代码分为框架代码和业务定制。业务定制类是使用单独的类加载器加载的,并且我们具有将更改提交给正在运行的生产实例的工具。每当我们需要在任何类中进行更改时,我们都会对其进行更改并将其提交给正在运行的实例。正在运行的实例将拒绝旧的类加载器,并使用新的类加载器实例再次加载类。这类似于Jboss的EJB热部署。