12 factors的第二个因素:“依赖”,指的是怎样,在什么地方,什么时候去管理应用的依赖
在经典的企业环境里面,我们曾经使用过一个叫做“Mommy Server”的服务器,这种服务器为应用提供了所有需要的资源,从满足应用的依赖到提供一个web server去承载应用。“Mommy server”的对立面是嵌入式的,自启动的服务器,所有运行应用需要的依赖都被包含在了一个构建好的组件里面
云模型是经典企业模型的成熟版本,因此,我们的应用需要不断的成长去充分利用云。应用不能假设服务器或者容器有它们需要的一切,相反应用需要自己去包含这些依赖。迁移到云,意味着需要把你的组织从“Mommy server”里面解脱出来
如果你构建应用的时候没有依赖容器模型的语言或者框架(Ruby,Go,Java with Spring Boot),你就已经走在了前面,不用担心“Mommy server”的问题了
大多数当代编程语言都会有一些机制去管理应用依赖,Maven 和 Gradle是Java世界比较流行的两个工具,.NET开发者用的是NuGet,Ruby用的是Bundler,go编程者用的是godeps.不考虑工具本身,这些工具都提供了类似的功能:他们允许开发者声明依赖,同时让工具去负责满足应用的依赖
许多工具同样有能力去隔离依赖,通常的做法是分析声明的依赖并且把这些依赖捆绑到某个子结构之下,或者在应用组件本身的内部
云原生应用程序永远不会隐性的依赖系统范围的软件包。对于Java,这意味着您的应用程序不能假定容器将管理服务器上的类路径,对于.NET,你的应用不能依赖全局的包缓存机制。Ruby开发者不能依赖于一个已经存在的中央位置。总而言之,你的代码不能依赖部署服务器上的已经存在的依赖
不合理的依赖隔离会引起数不清的问题,其中一些依赖相关的问题里面,比如某个开发者正在本地开发,并且使用到了某个依赖包的X版本,但是在生产环境的中央位置里面放了一个X+1的版本,这可能引起不可预知,很难察觉到的运行失败问题。如果任由这种情况发展,这种类型的失败可能会摧毁整个服务器,甚至给公司带来百万美元的损失
隔离依赖是指让依赖紧紧跟随应用一起发布,而不是将依赖放到某个中央的共享位置
正确管理应用程序的依赖关系是关于可重复部署的概念,应用程序应该力求走自动化路线。在理想的情况下,应用的容器是捆绑到应用发布的artifact里面,或者更好的情况下是应用最好没有容器
然后,对于一些企业,把server容器嵌入到应用里面是不太实际的,所以必须能够把发版的应用和server容器组合到一起,在云原生的Heroku上面,buildpack就是用来干这个事情的
遵守应用依赖管理的规则能够让你的应用离云原生更进一步