是否有一个十二因素应用程序的示例,专门针对.NET/TFS环境进行调整?

Adr*_*lie 12 .net tfs soa

有一个很好的文档称为"十二因素应用程序"(http://www.12factor.net/),其中作者试图定义设计,构建和部署现代应用程序的完美方式.服务.

该文档非常笼统,在许多情况下,所描述的实践并非最佳,不易实现或违反Microsoft的最佳实践.例如:文档不鼓励使用配置文件,而是使用环境变量进行配置.这在.NET中似乎是不正确的,其中使用XML配置文件是常见的(最好的?)实践.

在一个理想的世界中(即忘记预算/技术/技能限制),在一个组织中,Microsoft平台被选为所有部署和.NET/TFS的首选平台,选择开发环境/工具如何遵循指导在十二因素应用程序?

这样的应用程序是否有任何好的例子(也许是一个具有出色参考架构的开源应用程序)?

Joh*_*ers 12

我已阅读有关配置的部分,作者显然不了解.NET中配置文件的使用.他们表达的问题是我们过去常常遇到的.ini文件问题..NET不存在这些问题,因为:

  1. "桌面"应用程序将在每个部署中具有单个配置文件."app.config"将存在,因为program.exe.config已部署到与应用程序相同的文件夹中.
  2. 在Web应用程序中,web.config文件的层次结构将再次存在于定义明确的位置,并且具有明确定义的名称.
  3. Visual Studio 2010中的web.config转换功能允许将主配置文件检入源代码控制,以及指定如何为每个构建配置(环境)自动编辑主文件的转换文件.所有这些文件都可以存储在源代码管理中.
  4. 虽然将凭证存储在此类文件中是默认的(因此检入源代码管理中),但这不是必需的.
  5. 至少在Web应用程序的情况下,IIS的MSDEPLOY功能以及Visual Studio 2010的Web发布管道允许参数化部署.默认情况下,这包括连接字符串的参数化,连接字符串是可能发生凭据的主要区域之一.这可以扩展为包括所有凭据或其他敏感数据的参数化,以便开发人员无权访问此信息.可以在部署过程中填写参数.


Mat*_*son 7

12 Factor对配置有3个"要求".

  1. 不要将配置存储在代码中
  2. 不要将配置置于源代码管理中(或者以可能最终源代码控制的格式).他们想要一个"单一代码库".
  3. 将配置放在任何技术堆栈(.NET/Java/Ruby/..等)都可访问的格式中.

我会说.NET配置文件符合其中的一半.

  1. 配置文件不在代码中(传递).
  2. 配置文件不必在源代码管理中,但它们通常会在那里结束(失败).
  3. 尽管是XML格式并且可以被其他技术访问,但.NET配置文件有很多.NET主题.配置的模式由.NET类型提供,因此Java应用程序无法验证模式.(半学分).

虽然我同意他们的要求意图,但我认为他们对环境变量的建议是一个不好的建议.他们之所以选择环境变量,是因为他们将它们视为最低标准,并且可以在所有平台上使用,但它们实际上并非在所有平台上都可用.如果您在部分信任的Web应用程序(在共享托管平台上常见)中运行,则可能无法访问get/set环境变量.

每台机器设置环境变量.如果我必须对我的生产环境进行配置更改,我想在一个地方为所有服务器创建一次.环境变量不允许您这样做.

虽然我可以看到他们的观点,即您不希望所有开发人员都可以访问存储在版本控制中的秘密.控制配置的版本肯定有好处.当您的生产环境因配置更改而中断时,很容易问......"改变了什么"?某人只是ssh'ing到prod机器并设置环境变量留下的审计跟踪可能不那么容易追踪.话虽如此,我经常不会将配置文件存储在版本控制的同一部分中,而不是代码的其余部分.我将它们放在一个安全性受限的文件夹中,以便只有必要的人才需要访问.你可以想象,更进一步,把它们放在一个不同的项目中.

我愿意打赌他们违反了自己的规则,即不将配置放在文件中.例如.他们主页上的第一个要点是"使用声明式格式进行设置自动化,以最大限度地减少新开发人员加入项目的时间和成本;" 我打赌所有那些不应该放在文件中的配置设置都在厨师食谱中.要实现自动化的目标,您必须将它们保存在某个文件中.如果花了很多时间获得厨师食谱的人没有将它存储在某个版本控制中,我会感到惊讶.

我认为他们可以用不同的方式编写配置页面,只是说保持配置与代码分开.将它保存在单独的文件中(不要将其嵌入代码中),并将其单独存储在某处(不要将其放在同一个存储库中).您的部署过程会将这些重新组合在一起(代码和配置)到一个可部署的程序包中,但在此之前它们应该是分开的.

我对配置的建议是将配置视为"附加资源"并将其存储在后备存储(数据库)中.这使您的应用程序层更加无状态,这是他们的另一个目标.

  • 是的,您可以在一台机器上为每个用户设置它们,但这比每台机器更窄.我的观点是,很难在1000台服务器上同时设置环境变量. (2认同)

Not*_*tMe 5

设计中有许多问题,我认为有点幼稚。

例如,在后备服务部分,他们声明您应该能够在不考虑代码更改的情况下换出数据存储。

问题是,为了利用任何特定数据存储的性能和功能优势,您自然会倾向于利用您开始使用的存储的特定功能。

此外,并非每个数据存储都支持一组通用命令,以便您可以轻松地从一个移动到另一个。他们使用 MySql 或 CouchDB 的特定示例非常有趣,因为这两个 DB 系统在概念上非常不同:一个更像是传统的 RDBMS,另一个是基于文档的。您不能只是采用您的表结构并将其直接应用于 CouchDB 并期望向其抛出 SQL 命令。

这意味着您必须放置一个前端来基本上用一组公开为 Web 服务的命令来包装每个特定的数据存储......恕我直言,这使得开发变得更加困难(如果有的话)很少有好处。

现在,如果他们将其限制为将类似服务器(本地 mysql)交换到远程服务器(Amazon RDS),那么通过 url 访问数据存储资源的要求是无关紧要的。此外,不需要为该移动发生代码更改的要求是不必要的,因为您不必更改代码只是为了支持在不同的服务器上运行您的确切数据库。


以上只是我诚实地看的第一个区域。正如约翰桑德斯所说,配置一也表明完全缺乏对 .Net 等技术的了解。坦率地说,整件事看起来像是由一个在 Ruby 世界里呆了一段时间的人写的,还没有看过那里的其他东西。

  • Chris,备份服务部分中使用的示例说,应该能够用从备份恢复的新实例替换出现故障的数据存储。对我来说,这意味着它与您的倒数第二个点地址具有相同的数据存储风格。 (5认同)
  • 谢谢,克里斯,这是有价值的批评。基于迄今为止你自己、Matt 和 John 的答案,我建议 12 因素方法非常适用于混合了可互换技术(PHP、Ruby、MySQL 等)的“解耦”环境,但不适用于强连接的堆栈,如MS 堆栈,其中每一层都有可以通过坚持环境特定的最佳实践来实现的好处。 (2认同)