文档结构  
可译网翻译有奖活动正在进行中,查看详情 现在前往 注册?
原作者:Pieter Humphrey (2016-10-04)    来源:Dzone [英文]
CY2    计算机    2016-10-04    0评/2103阅
翻译进度:已翻译   参与翻译: 薯片番茄 (8), toypipi (6), learner (1)

对于许多人来说,“原生云”和“应用程序的12要素”是同义词。本文的目的是为了说明,对于原生云,除了坚持基本的12大要素外,还有一些其他的因素。在大多数情况下,Java 能胜任这一任务。在本文中,我们将对其概念和代码示例进行研究,看看在标准的12个要素以外,还存在哪些因素, 正如Kevin Hoffmann 最近在 O’Reilly 出版的书上提到了超越 12 个因素的应用。

1. 单个代码库

虽然少了一个特定的 Java 概念,这个因素一般是指单个代码库在源代码控制或管理一组的存储库是来自于一个共同的根源。 获取单个代码库 使它的构建更简洁,并在各种环境下推出任意数量不同的发布版本。当你的应用程序是由一打或者更多的代码库构成的,那么这就是最好的反面案例。虽然使用一个代码库来生产多种可以工作的应用程序是可行的,但其目标是在应用和代码库间生成一对一的关系。虽说操作通过一个代码库就可以做到,但也充满挑战。有时候,对一个团队或者组织来说,一个应用程序对应一个代码库是最简单的关系。

第 1 段(可获 2.59 积分)

2. 依赖管理

大多数 Java (以及 Groovy) 开发者可以利用像 Maven (以及 Gradle) 这样的工具,来声明你的应用程序正确构建和执行所需的依赖项。这个想法还可以让工具确保这些依赖关系得到满足,同时把它们打包成一个单一的二进制部署的工件(artifact)。像 Maven Shade 或 Spring Boot 这些插件可以将你的应用程序及其依赖项打包进单个 “uberjar” 或者 “fat jar” 文件中,从而提供了隔离这些依赖关系的方法。

第 2 段(可获 1.14 积分)

图1是示例Spring Boot应用程序Maven构建文件pom.xml的一部分。 显示了开发人员指定的依赖性声明。

图1:显示应用程序依赖关系的POM.xml的一部分

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository
    -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>
第 3 段(可获 0.45 积分)

 

图2是在同一应用程序内列出的依赖性的一部分,显示了捆绑到应用程序的uberjar中的JAR包,其将这些依赖关系与底层环境中的变化隔离。 应用程序将依赖于这些依赖关系,而不是部署目标中存在的潜在冲突的库。

图2:MVN依赖的一部分:一个示例应用程序树

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building quote-service 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @quote-service ---
[INFO] com.example:quote-service:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.cloud:spring-cloud-starterconfig:jar:1.1.3.RELEASE:compile
[INFO] | +- org.springframework.cloud:spring-cloud-starter:jar:1.1.1.RELEASE:compile
[INFO] | | +- org.springframework.cloud:spring-cloud-context:jar:1.1.1.RELEASE:compile
[INFO] | | | \- org.springframework.security:springsecurity-crypto:jar:4.0.4.RELEASE:compile
[INFO] | | +- org.springframework.cloud:spring-cloud-commons:jar:1.1.1.RELEASE:compile
[INFO] | | \- org.springframework.security:spring-securityrsa:jar:1.0.1.RELEASE:compile
[INFO] | | \- org.bouncycastle:bcpkixjdk15on:jar:1.47:compile
[INFO] | | \- org.bouncycastle:bcprovjdk15on:jar:1.47:compile
[INFO] | +- org.springframework.cloud:spring-cloud-configclient:jar:1.1.2.RELEASE:compile
[INFO] | | \- org.springframework.boot:spring-boot-autoconfigure:jar:1.3.7.RELEASE:compile
[INFO] | \- com.fasterxml.jackson.core:jacksondatabind:jar:2.6.7:compile
[INFO] | \- com.fasterxml.jackson.core:jacksoncore:jar:2.6.7:compile
[INFO] +- org.springframework.cloud:spring-cloud-startereureka:jar:1.1.5.RELEASE:compile
[INFO] | +- org.springframework.cloud:spring-cloud-netflixcore:jar:1.1.5.RELEASE:compile
[INFO] | | \- org.springframework.boot:springboot:jar:1.3.7.RELEASE:compile
第 4 段(可获 0.74 积分)

3. 编译,发布,运行

一个独立的代码库是通过编译构成并生成独立构件;然后和项目外部的配置信息进行合并。代码库随后被发布到云环境下运行。千万不要在运行期间改变代码。由于系统提供了使用相同方式把构件组装到一起的单独的位置,编译的思想在于自然地过渡到下一步的集成 (CI)。

现代的Java框架可以生成uberjars文件,或者更传统的WAR文件, 这些文件作为独立的容易集成的构件。发布阶段主要是合并外部的配置信息(参考下面的配置)和独立的项目构件以及像JDK,OS,和Tomcat这样的依赖。目的是生成可执行的、版本化的、可以撤销的发布版本。云平台拿到发布版本后使用一种严格独立的方式来处理运行阶段。

第 5 段(可获 1.69 积分)

4. 配置

这一要素是具体化配置的形式,随着部署环境的变化有所不同。(开发, 演示, 生产). 配置信息无处不在: 分布在应用的代码中, 在如YAML这样的属性源文件中, Java属性, 环境变量, CLI参数, 系统参数, JNDI, 等等。有多重解决方案—重构代码以寻找环境变量。

对于简单的系统, 一个最直接的方案是使用Java的System.getenv()功能从环境中拿到一个或者多个配置信息,或者全部key值和value值的Map. 图 3是代码示例.

 

第 6 段(可获 1.24 积分)

图 3: POM.xml的一部分,显示应用程序依赖关系

private String userName = System.getenv(“BACKINGSERVICE_UID”);
private String password = System.getenv(“BACKINGSERVICE_PASSWORD”);

对于更复杂的系统, Spring CloudSpring Boot 更流行,它们提供了强大的功能来控制源文件以及解析配置数据。

5. 日志

日志应该被视为事件流:一个由应用产生的具有时序性的事件序列。 因为你不能使用文件的形式在云上记录日志,所以你要你需要将日志输入到stdout/stderr上,让云端提供者或相关工具来处理。例如, Cloud Foundry的loggregator将日志以流的形式输出,以供日志聚合和集中管理。在java中以stdout/stderr的方式记录日志的简单实例如下:

第 7 段(可获 1.3 积分)
Logger log = Logger.getLogger(MyClass.class.getName());
log.setLevel(Level.ALL);
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleFormatter());
log.addHandler(handler);
handler.setLevel(Level.ALL);
log.fine(“This is fine.”);

 

6. 自由支配

 如果一段流程需要一段时间来启动或关闭,那么该流程需要分离一个后台服务并优化提高相应性能。
一个依赖云建立的程序是可自由支配的—它能在任何时间被创建或者销毁。这种设计有助于确保服务长时间运行良好,并且使你从这种类似于自动扩展的特性中受益。

第 8 段(可获 0.78 积分)

7. 支持服务

一个支持服务是一些你的app依赖的外部事物,例如一个数据库或者一个消息服务器。 app应该以外部配置的方式声明所需的支持服务,例如YAML或者一个跟踪配置服务。一个云平台处理绑定你的app到相应服务,理想情况下绑定或重新绑定不需要重新启动你的app。这种松耦合有许多优势,例如允许你使用断路器模式优雅地处理一个强迫停运的情景

8. 环境一致

共同开发和QA沙箱环境,从生产规模和可靠性角度与生产环境比都有不同,但你不能使用一个“雪花”(差距过大,无法正确评估性能)环境!云平台保持多app环境一致并且可以消除调试环境的差异。

第 9 段(可获 1.48 积分)

9. 管理流程

这些就像计时器任务,一次性脚本,以及其他你使用shell编程可能做的事情。来自云平台的支持服务和其他功能可以帮助运行这些, 虽然Java(目前)没有提供像Python或Ruby这样的shell,但是生态系统有很多选项,可以方便地运行一次性任务或者创建一个shell接口

10. 端口绑定

在非云环境中,通常能看到几个应用程序在同一个容器中运行,通过端口号分隔每个应用程序,然后使用DNS提供一个友好的名称来访问。 而在云端,你避免了这种微管理——云提供者会根据进程和缩放比例来管理端口分支。

第 10 段(可获 1.53 积分)

虽然它可能依赖外部机制,为您的app提供流量,但这些机制在容器、机器与平台之间各不同。端口绑定为你提供全量控制,提示你该如何接收与响应应用请求,而不管其部署在哪里。

11. 进程

这里提及的原始12-因素定义指出app是无状态的。但是,有一些状态需要出现在指定的地方。沿着这些线,这个因素提倡将任何长期运行的状态转换为高速缓存或者数据存储,来实现外部的、逻辑的支撑服务。

第 11 段(可获 1.15 积分)

12. 并发

云平台构建为可以水平扩展。 这里的设计考虑到 - 你的应用程序应该是一次性的,无状态的,并使用无共享的过程。 使用平台的流程管理模型对于利用自动缩放,blue-green部署等功能非常重要。

13. 超越12因素:遥测,安全,API-First 设计

12个因素创作于2012年左右。让我们来看看现代云中的一些基本功能,使你的应用程序可持续发展:

第 12 段(可获 1.16 积分)

在云计算中,Java应用程序日志可以简单地定向到stdout / stderr,在那里它们被流式传输以及做聚合运算。 Spring Boot使JMX变得轻松,商业云平台可以提供高级功能,如APM。

你的应用程序外部的安全性,应用于使用RBAC的应用程序端点(URL),对于使用SSO和OAUTH2提供程序集成的云平台很重要。 否则,多个Java应用程序的安全性将变得难以管理。

超越12因素应用程序描述了API-first方法作为“一种contract-first模式的扩展,其中开发者首先集中在构建其应用的边缘或接缝。 随着通过CI服务器连续测试的集成点,团队可以在他们自己的服务上工作,而且仍然能够保证,一切都将正常工作。

第 13 段(可获 1.55 积分)

平台革新

总之,重要的是要意识到,只是重新配置现有的应用程序在云上运行,你不需要所有15个因素。 这种云本地成熟度模型(由大型金融服务组织表示)说明了一种接触大型复杂的单片应用程序的过程并增量地使用“12 factorize”法。

更多Java的好处

有关Jigsaw,反应式微服务的更多见解,以及获取更多免费副本的新的现代Java DZone指南,第二卷!

如果你想看到指南中的其他文章,看看:

第 14 段(可获 1.44 积分)

从构思到应用程序,为您提供在开放标准的基于云的平台上快速构建,管理和运行一系列应用程序(Web,移动,大数据,新型智能设备等)的架构。 了解开发人员为什么使用IBM Bluemix。 与 IBM.合作。

第 15 段(可获 2 积分)

文章评论