尽可能的保持开发,预发布,线上环境相同
从以往经验来看,开发环境(即开发人员的本地部署)和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面:
- 时间差异:开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。
- 人员差异:开发人员编写代码,运维人员部署代码。
- 工具差异:开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。
12-Factor 应用想要做到持续部署就必须缩小本地与线上差异。
再回头看上面所描述的三个差异:
- 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。
- 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。
- 缩小工具差异:尽量保证开发环境以及线上环境的一致性。
上述总结:
对比 | 传统应用 | 12-Factor 应用 |
---|---|---|
每次部署间隔 | 数周 | 几小时 |
开发人员 vs 运维人员 | 不同的人 | 相同的人 |
开发环境 vs 线上环境 | 不同 | 尽量接近 |
后端服务是保持开发与线上等价的重要部分
例如数据库,队列系统,以及缓存。许多语言都提供了简化获取后端服务的类库,例如不同类型服务的适配器。下列表格提供了一些例子。
类型 | 语言 | 类库 | 适配器 |
---|---|---|---|
数据库 | Ruby/Rails | ActiveRecord | MySQL, PostgreSQL, SQLite |
队列 | Python/Django | Celery | RabbitMQ, Beanstalkd, Redis |
缓存 | Ruby/Rails | ActiveSupport::Cache | Memory, filesystem, Memcached |
开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力,而那些更重量级的健壮的后端服务应该使用在生产环境。例如,本地使用 SQLite 线上使用 PostgreSQL;又如本地缓存在进程内存中而线上存入 Memcached。
12-Factor 应用的开发人员应该反对在不同环境间使用不同的后端服务 ,即使适配器已经可以几乎消除使用上的差异。
这是因为,不同的后端服务意味着会突然出现的不兼容,从而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看,消除这种阻力需要花费很大的代价。
与此同时,轻量的本地服务也不像以前那样引人注目。借助于 Homebrew,apt-get 等现代的打包系统,诸如Memcached、PostgreSQL、RabbitMQ 等后端服务的安装与运行也并不复杂。此外,使用类似 Chef 和 Puppet 的声明式配置工具,结合像 Vagrant 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。
不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的相同版本。
很多公司因为分工很明确,代码是开发写的,生产环境和运行是运维的事情。作为负责开发,要从需求的正确性到往后,整个代码的正确性都是应该负责的。机器太慢的情况已经比较少见了,所以我们尽量保证开发的环境和运行的环境是一样的。持续集成很重要,其实很多人,特别是小团队可能会觉得持续集成,搞测试是一件很烦的事情。其实不是的,你要很简易的搭一个不断地跑测试的服务器是很重要的。它会往这个服务发一个HTTP的包,不管成功、失败会发出来一份文件。这种情况回归测试是很重要的,遇到一个bug,写一个测试能够重现它。下一次这个测试会直接告诉你怎样做的,将来这个代码不可维护了。任何的改动破坏到原来的东西,测试都会跑不过。环境等价是特别重要的一点。如果每个系统都往文件里面写的话,每一个日志都会分摊在不同的地方,一旦出了问题,你都不知道该去看哪里的日志了。
参考:
网友评论