├── .gitignore ├── Cloud_Native_Spring_in_Action_v10.pdf ├── README.md └── cn-translate ├── 01-Introduction-to-cloud-native ├── 1.1-What-is-cloud-native │ ├── 1.1.1-The-Three-Ps-of-Cloud-Native.md │ └── Introduction.md ├── 1.2-The-cloud-and-the-cloud-computing-model │ ├── 1.2.1-Infrastructure-as-a-Service.md │ ├── 1.2.2-Container-as-a-Service.md │ ├── 1.2.3-Platform-as-a-Service.md │ ├── 1.2.4-Function-as-a-Service.md │ ├── 1.2.5-Software-as-a-Service.md │ └── Introduction.md ├── 1.3-Properties-of-cloud-native-applications │ ├── 1.3.1-Scalability.md │ ├── 1.3.2-Loose-coupling.md │ ├── 1.3.3-Resilience.md │ ├── 1.3.4-Observability.md │ ├── 1.3.5-Manageability.md │ └── Introduction.md ├── 1.4-Culture-and-practices-supporting-cloud-native │ ├── 1.4.1-Automation.md │ ├── 1.4.2-Continuous-delivery.md │ ├── 1.4.3-DevOps.md │ └── Introduction.md ├── 1.5-Is-the-cloud-your-best-option │ ├── 1.5.1-Speed.md │ ├── 1.5.2-Resilience.md │ ├── 1.5.3-Scale.md │ ├── 1.5.4-Cost.md │ └── Introduction.md ├── 1.6-Cloud-native-topologies │ ├── 1.6.1-Containers.md │ ├── 1.6.2-Orchestration.md │ ├── 1.6.3-Serverless.md │ └── Introduction.md ├── 1.7-Architectures-for-cloud-native-applications │ ├── 1.7.1-From-multi-tiered-to-microservice-architectures-and-beyond.md │ ├── 1.7.2-Service-based-architecture-for-cloud-native-applications.md │ └── Introduction.md ├── Introduction.md └── Summary.md ├── 02-Cloud-native-patterns-and-technologies ├── 2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond │ ├── 2.1.1-One-codebase-one-application.md │ ├── 2.1.10-Administrative-processes.md │ ├── 2.1.11-Port-binding.md │ ├── 2.1.12-Stateless-processes.md │ ├── 2.1.13-Concurrency.md │ ├── 2.1.14-Telemetry.md │ ├── 2.1.15-Authentication-and-authorization.md │ ├── 2.1.2-API-first.md │ ├── 2.1.3-Dependency-management.md │ ├── 2.1.4-Design-build-release-run.md │ ├── 2.1.5-Configuration-credentials-and-code.md │ ├── 2.1.6-Logs.md │ ├── 2.1.7-Disposability.md │ ├── 2.1.8-Backing-services.md │ ├── 2.1.9-Environment-parity.md │ └── Introduction.md ├── 2.2-Building-cloud-native-applications-with-Spring │ ├── 2.2.1-Overview-of-the-Spring-landscape.md │ ├── 2.2.2-Building-a-Spring-Boot-application.md │ └── Introduction.md ├── 2.3-Containerizing-applications-with-Docker │ ├── 2.3.1-Introducing-Docker-Images-and-containers.md │ ├── 2.3.2-Running-a-Spring-application-as-a-container.md │ └── Introduction.md ├── 2.4-Managing-containers-with-Kubernetes │ ├── 2.4.1-Introducing-Kubernetes-Deployments-pods-and-services.md │ ├── 2.4.2-Running-a-Spring-application-on-Kubernetes.md │ └── Introduction.md ├── 2.5-Polar-Bookshop-A-cloud-native-application │ ├── 2.5.1-Understanding-the-requirements-of-the-system.md │ ├── 2.5.2-Exploring-patterns-and-technologies-used-in-the-project.md │ └── Introduction.md ├── Introduction.md └── Summary.md ├── 03-Getting-started-with-cloud-native-development ├── 3.1-Bootstrapping-a-cloud-native-project │ ├── 3.1.1-One-codebase-one-application.md │ ├── 3.1.2-Dependency-management-with-Gradle-and-Maven.md │ └── Introduction.md ├── 3.2-Working-with-embedded-servers │ ├── 3.2.1-Executable-JARs-and-embedded-servers-Ready-for-the-cloud.md │ ├── 3.2.2-Understanding-the-thread-per-request-model.md │ ├── 3.2.3-Configuring-the-embedded-Tomcat.md │ └── Introduction.md ├── 3.3-Building-a-RESTful-application-with-Spring-MVC │ ├── 3.3.1-REST-API-first-business-logic-later.md │ ├── 3.3.2-Implementing-a-REST-API-with-Spring-MVC.md │ ├── 3.3.3-Data-validation-and-error-handling.md │ ├── 3.3.4-Evolving-APIs-for-future-requirements.md │ └── Introduction.md ├── 3.4-Testing-a-RESTful-application-with-Spring │ ├── 3.4.1-Unit-tests-with-JUnit-5.md │ ├── 3.4.2-Integration-tests-with-SpringBootTest.md │ ├── 3.4.3-Testing-REST-controllers-with-WebMvcTest.md │ ├── 3.4.4-Testing-the-JSON-serialization-with-JsonTest.md │ └── Introduction.md ├── 3.5-Continuous-integration-pipelines-with-GitHub-Actions │ ├── 3.5.1-GitHub-Actions-Automating-builds-and-tests.md │ └── Introduction.md ├── Introduction.md └── Summary.md ├── 04-Externalized-configuration-management ├── 4.1-Configuration-in-Spring-properties-and-profiles │ ├── 4.1.1-Properties-Key-value-pairs-for-configuration.md │ ├── 4.1.2-Profiles-Feature-flags-and-configuration-groups.md │ └── Introduction.md ├── 4.2-Externalized-configuration-one-build-multiple-configurations │ ├── 4.2.1-Configuring-an-application-through-command-line-arguments.md │ ├── 4.2.2-Configuring-an-application-through-JVM-system-properties.md │ ├── 4.2.3-Configuring-an-application-through-environment-variables.md │ └── Introduction.md ├── 4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server │ ├── 4.3.1-Using-Git-to-store-your-configuration-data.md │ ├── 4.3.2-Setting-up-a-configuration-server.md │ ├── 4.3.3-Making-the-configuration-server-resilient.md │ ├── 4.3.4-Understanding-the-configuration-server-REST-API.md │ ├── 4.4.1-Setting-up-a-configuration-client.md │ ├── 4.4.2-Making-the-configuration-client-resilient.md │ ├── 4.4.3-Refreshing-configuration-at-runtime.md │ └── Introduction.md ├── 4.4-Using-a-configuration-server-with-Spring-Cloud-Config-Client │ └── Introduction.md ├── Introduction.md └── Summary.md ├── README.md ├── SUMMARY.md ├── assets ├── 00-Vitale-CNS-MEAP-HI.png ├── 1.1.jpg ├── 1.10.jpg ├── 1.11.jpg ├── 1.12.jpg ├── 1.13.jpg ├── 1.14.jpg ├── 1.2.jpg ├── 1.3.jpg ├── 1.4.jpg ├── 1.5.jpg ├── 1.6.jpg ├── 1.7.jpg ├── 1.8.jpg ├── 1.9.jpg ├── 2.1.jpg ├── 2.10.jpg ├── 2.11.jpg ├── 2.12.jpg ├── 2.13.jpg ├── 2.14.jpg ├── 2.15.jpg ├── 2.2.jpg ├── 2.3.jpg ├── 2.4.jpg ├── 2.5.jpg ├── 2.6.jpg ├── 2.7.jpg ├── 2.8.jpg ├── 2.9.jpg ├── 4.1.jpg ├── 4.2.jpg ├── 4.3.jpg └── 4.4.jpg ├── book.json └── welcome.md /.gitignore: -------------------------------------------------------------------------------- 1 | cn-translate/node_modules/* 2 | cn-translate/_book/* 3 | -------------------------------------------------------------------------------- /Cloud_Native_Spring_in_Action_v10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/Cloud_Native_Spring_in_Action_v10.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 云原生 Spring 实战 (基于 Spring boot 和 Kubernetes) 2 | 3 | 《Cloud Native Spring in Action With Spring Boot and Kubernetes》 预计将于 2022 年夏出版。现在的翻译基于 Manning 出版社的 MEAP 版本。 4 | 5 | ![](cn-translate/assets/00-Vitale-CNS-MEAP-HI.png) 6 | 7 | 地址:https://www.manning.com/books/cloud-native-spring-in-action 8 | 9 | LiveBook: https://livebook.manning.com/book/cloud-native-spring-in-action 10 | 11 | 源码地址:https://github.com/ThomasVitale/cloud-native-spring-in-action 12 | 13 | 14 | ## 强烈推荐您购买此书 15 | ## 尊重作者,保护版权 16 | 17 | 翻译说明: 18 | * 中文翻译工作都在 cn-translate 目录下 19 | * 书中使用到的图片都放在 cn-translate/assets 目录下,使用时注意路径。 20 | * 翻译中所有涉及读者称谓的都用 **`您`**,不用 `你`。 21 | * 引用书中的代码时标识语言,如:` ```java ` 22 | * 引用配置时指定类型,如: ` ```yaml 或 ```xml ` 23 | * 引用命令时指定类型,如` ```bash ` 24 | 25 | 26 | **进度:** 27 | 28 | | 章节 | 完成度 | 翻译人 | 29 | | :--- | :--- | :--- | 30 | | Welcome | 完成 | leonli0102 | 31 | | Part 1 Cloud Native | | 32 | | 1 - Introduction to cloud native | 完成 | leonli0102 | 33 | | 2 - Cloud native patterns and technologies | 完成 | leonli0102 | 34 | | 3 - Getting started with cloud native development | **进行中** | leonli0102 | 35 | | 4 - Externalized configuration management | **进行中** | leonli0102 | 36 | 37 | GitHub地址:[https://github.com/LeonLi0102/cloud-native-spring-in-action-translate.git](https://github.com/LeonLi0102/cloud-native-spring-in-action-translate.git) 38 | 39 | 40 | GitBook地址:[https://leonli0102.github.io/cloud-native-spring-in-action/](https://leonli0102.github.io/cloud-native-spring-in-action/) 41 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.1-What-is-cloud-native/1.1.1-The-Three-Ps-of-Cloud-Native.md: -------------------------------------------------------------------------------- 1 | ### 1.1.1 什么是云原生 2 | 3 | 专门为云设计的应用程序到底意味着什么呢?云原生计算基金会(CNCF)在其云原生定义中回答了这个问题。 4 | 5 | _云原生技术使组织可以构建和运行可扩展的应用程序,这些应用运行在现代的、动态的环境中,如公有云、私有云和混合云。容器、服务网格、微服务、不变的基础设施和声明式 API 就是典型的示例。_ 6 | 7 | _这些技术使松散耦合的系统具有弹性、可管理性和可观测性。与强大的自动化相结合,它们允许工程师用最少的劳动,进行频繁的和可预测的重大功能更新。_ 8 | 9 | 根据这个定义,我确定了三组信息,我称之为云原生的 3 个 P: 10 | 11 | * 位置(Place)。云原生应用程序的运行环境是现代的、动态的环境:云(公共云、私有云或混合云)。 12 | * 特性(Properties)。云原生应用程序是可伸缩的、松耦合、有弹性、可管理、可观测的。 13 | * 实施(Practices)。围绕云原生应用程序的实践包括健壮的自动化、结合频繁且可预测的更改:自动化、持续交付和 DevOPs。 14 | 15 | >什么是云原生计算基金会? 16 | > 17 | >云原生计算基金会(CNCF),是 Linux 基金会的一部分。致力于构建可持续的生态系统,促进社区支持云原生开源软件的增长和健康。CNCF 主办了许多云原生技术和项目,以支持云的可移植性,但并没有固定供应商。如果您想寻找云原生方面的项目,我建议查看 CNCF 云原生互动全景。 18 | 19 | 在以下部分中,我们将进一步研究这些概念。不过,首先,我希望您注意,云原生的定义是与任何特定的实现或细节无关的。CNCF 在定义中提到的这些,比如容器和微服务,都只是例子。最常见的误解是,在开始迁移到云时您必须采用微服务架构并构建容器。然而事实并非如此。Fremantle 在 2010 年的文章就是证明。他没有提到这些,因为当时这些技术都不存在。然而,他所描述的应用程序不仅仍然被认为是云原生的,而且还被认为是符合 CNCF 八年后给出的定义的。 20 | 21 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.1-What-is-cloud-native/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.1 什么是云原生 2 | 3 | 2010 年 5 月 25 日,云计算行业的老手 Paul Fremantle 在他的博客上写了一篇题为“Cloud Native”的文章。他是最早使用 `云原生`一词的人之一。在一个诸如微服务、Docker、DevOps、Kubernetes 或 Spring Boot 等概念和技术尚不存在的时期,Fremantle 与他的 WSO2 团队讨论了如何让“应用程序和中间件在云环境中良好工作”,也就是云原生。 4 | 5 | Fremantle 解释的关键概念是,应用程序应专门为云设计,并具有利用其运行的新环境和云计算模型的特性。您可以将一个传统的应用程序(设计为在非云环境运行)移动到云上,这种方法通常被称为“升移”的方法,但这并不意味着应用是云原生的。让我们看看什么样的才是云原生。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.1-Infrastructure-as-a-Service.md: -------------------------------------------------------------------------------- 1 | ### 1.2.1 基础设施即服务 2 | 3 | 在基础设施即服务(IaaS)模型中,消费者可以直接控制提供的资源,如服务器、存储和网络等。例如,他们可以配置虚拟机并安装操作系统和库等软件。这个模型已经被使用相当长的时间了,直到亚马逊在 2006 年因推出 Amazon Web Services 使其大受欢迎。IaaS 产品的例子有 Amazon Elastic Compute Cloud(EC2),Microsoft Azure Virtual Machines 和 Google Compute Engine。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.2-Container-as-a-Service.md: -------------------------------------------------------------------------------- 1 | ### 1.2.2 容器即服务 2 | 3 | 使用容器即服务(CaaS)模型,使用者不能控制原始虚拟化资源。相反,他们管理的是容器。云服务商将提供满足这些容器所需的底层资源。例如,启动新的虚拟机并配置网络以使其可通过互联网访问。Docker Swarm 和 Kubernetes 提供的是 CaaS 级别的服务。所有主要云服务商都提供托管 Kubernetes 服务,这已成为事实上的 CaaS 标准:Amazon Elastic Kubernetes Service(EKS)、Microsoft Azure Kubernetes Service(AKS)和 Google Kubernetes Engine(GKE)。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.3-Platform-as-a-Service.md: -------------------------------------------------------------------------------- 1 | ### 1.2.3 平台即服务 2 | 3 | 在平台即服务(PaaS)模型中,云服务商管理栈直至运行时和容器级别。消费者运行和管理应用程序,而平台处理其余所有事情。例如,作为开发人员,您可以构建 Java 应用程序,将其打包为 JAR 文件,然后将其部署到根据 PaaS 模型工作的平台。平台提供 Java 运行时和其他必需的中间件,还可以提供其他服务,如数据库或消息传递系统。PaaS 产品的例子有 Cloud Foundry、Heroku 和 AWS 4 | Elastic Beanstalk 和 Google App Engine。 5 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.4-Function-as-a-Service.md: -------------------------------------------------------------------------------- 1 | ### 1.2.4 功能即服务 2 | 3 | 功能即服务(FaaS)模型利用无服务器计算让消费者管理由事件触发的功能。云提供处理所有其余事情。在这个模型中,开发人员构建单个功能,而不是整个应用程序。FaaS 平台配置何时应执行此类功能。例如,您可以编写一个函数,该函数在消息队列可用时分析数据集并计算结果。FaaS 产品的例子有 Amazon AWS Lambda、Microsoft Azure Functions 和 Google Cloud Functions。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.5-Software-as-a-Service.md: -------------------------------------------------------------------------------- 1 | ### 1.2.5 软件即服务 2 | 3 | 抽象程度最高的服务是软件即服务(SaaS)。在这个模型中,消费者只能作为用户访问应用程序,而云服务商管理整个应用程序堆栈。许多公司构建应用程序,使用 CaaS 或 PaaS 模型运行它们,然后将其作为 SaaS 销售给终端客户。SaaS 应用程序的消费者通常使用 4 | 瘦客户端 web 浏览器来访问它们。作为 SaaS 提供的应用程序示例如下 Salesforce、ProtonMail 和 Microsoft Office 365。 5 | 6 | > **Platform 还是 PaaS 服务** 7 | > 8 | > 平台(Platform)这个术语可能会在云计算中产生一些混乱。让我们讨论澄清一下。通常,平台是一个操作环境,用于运行和管理应用程序。所以,Google Kubernetes Engine(GKE)是一个根据 CaaS 模型提供云服务的平台。Microsoft Azure Functions 是一个提供以 FaaS 为模型服务的平台。在较低的级别上,如果您将应用程序直接部署在 Ubuntu 机器上,那台机器就是您的平台。在书的其余部分,每当我使用平台(Platform)这个术语时,除非单独说明,我指的是刚才解释的这个更广泛的概念。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.2 云和云计算模型 2 | 3 | 在关注主要角色,即云原生应用程序之前,我想先介描述一下我们这个旅程发生的地点,也是云原生应用程序运行的环境:云。如下图所示,我将在本节中定义云及其主要特性。如图 1.2 所总结的,如果云原生应用程序设计为在云环境中良好运行,您应该要知道那是什么样的环境。 4 | 5 | ![](../../assets/1.2.jpg) 6 | 7 | **图 1.2 云是一种以不同计算模型为特性的 IT 基础设施,云供应商根据消费者需求的不同控制程度来提供服务。**
8 | 9 | 云是一种根据云计算模型,支持向消费者交付计算资源的 IT 基础设施。国家标准与技术研究所(NIST)对云计算的定义如下: 10 | 11 | *云计算是一种模型,它支持对网络进行无处不在、方便的按需访问可配置计算资源的共享池(例如,网络、服务器、存储器、应用程序和服务等),可以用最少的管理工作与服务提供者交互。* 12 | 13 | 就像你从供应商那里获得电力,而不是自己发电一样。通过云您可以获得作为商品的计算资源(例如,服务器、存储和网络)。 14 | 15 | 云提供商管理底层云基础设施,因此消费者无需担心机器或网络等物理资源。迁移到云的公司可以通过网络(通常是 Internet)获取计算资源。通常会使用一组 API 形成自助服务,根据需要按需调配和扩展资源。 16 | 17 | 弹性是该模型的主要特性之一:计算资源可以根据需求动态调配和发布。 18 | 19 | *弹性是指系统能够通过资源调配来适应工作负载变化的程度,以自主方式进行资源调配,以便在每个时间点,使可用资源与当前需求尽可能匹配。* 20 | 21 | 传统 IT 基础设施无法提供弹性能力。公司必须计算所需的最大计算能力,并建立支持该能力的基础设施,即使大部分情况下只是偶尔需要。随着云计算模型的出现,计算资源受到监控,消费者只为他们实际使用的东西付费。 22 | 23 | 对于云基础设施应该在哪里或应该由谁提供,没有严格的要求。云服务有几种部署模型,主要是私有云、公共云和混合云。 24 | 25 | * 私有云。为单个组织使用而配置的云基础架构。可以由组织本身或第三方管理,也可以内部部署或外部托管。对于要处理敏感数据或非常关键系统的组织,私有云通常是云计算的首选选项。这也是一个常见选择,完全控制基础设施以符合特定法律和法规,像《通用数据保护条例》(GDPR)或《加州消费者隐私法》(CCPA)。例如,银行和医疗服务提供商很可能建立自己的云基础设施。 26 | 27 | * 公共云。为公共使用而配置的云基础架构。它通常是由某组织所有并提供管理,也就是云服务商,都托管在提供商的场所。公有云服务提供商的例子有 Amazon Web Services(AWS)、Microsoft Azure 和 Google Cloud。 28 | 29 | * 混合云。由两个或多个不同的云基础架构组成,由前面的类型绑定在一起并提供服务,就好像它们是一个单一的环境。 30 | 31 | 云计算模型提供了五种主要的服务模型,具体取决于给消费者提供哪些功能。关于选择哪种服务模型的决策,应该是由消费者对基础设施的需求控制程度,以及他们需要管理的哪种类型的计算资源。图 1.3 显示了领先的云计算服务与传统基础设施的比较模型,并显示了维护每个基础设施级别的人员:消费者或云提供商。 32 | 33 | ![](../../assets/1.3.jpg) 34 | 35 | **图 1.3 云计算服务模型。它们的不同之处在于它们提供的抽象级别(例如,使用 IaaS,用户管理虚拟机)以及谁负责管理哪些虚拟机级别(例如,对于 CaaS,使用者管理容器,提供者管理底层容器基础设施)。** 36 | 37 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.1-Scalability.md: -------------------------------------------------------------------------------- 1 | ### 1.3.1 扩展性 2 | 3 | 云原生应用程序是可扩展的,这意味着如果需要,它可以为不断增加的工作负载提供额外的资源。根据这些额外资源的性质,可分为垂直扩展和水平扩展。 4 | 5 | * **垂直扩展**。垂直缩放或上下缩放,这意味着给计算节点添加或删除硬件资源,如 CPU 或 内存。这种方法是有限度的,因为不可能无限添加硬件资源。另一方面,应用程序不需要做什么特殊设计就可以缩放。 6 | 7 | * **水平扩展**。水平缩放或内外缩放,意味着添加更多计算节点或容器(例如,当使用 Kubernetes 时)到系统中。这种方法与垂直扩展不同,几乎没有限制,但它需要应用程序要特别处理以支持水平扩展。 8 | 9 | 传统系统通常会在工作负载增加的情况下采用垂直扩展。添加 CPU 和内存是应用程序支持更多用户,而无需(重新)设计以实现扩展的常用方法。在特定情况下,这仍然是一个不错的选择,但是云需要其他东西。 10 | 11 | 在云中,一切都是动态不断变化的,水平扩展是首选。基于云计算模型提供的抽象级别,可以直接启动应用程序的新实例,而不是增加已经运行的机器的计算能力。因为云是有弹性的,所以可以在短时间内动态地进行缩放。我把弹性作为一个主要特性来讨论:根据需求主动采取行动,调配和释放计算资源。可伸缩性是弹性的先决条件。 12 | 13 | 图 1.5 显示了垂直扩展和水平扩展之间的区别。在垂直扩展情况下,我们通过向现有虚拟机添加更多资源来扩展。在水平扩展情况下,我们添加另一个虚拟机,以帮助现有虚拟机处理额外的工作负载。 14 | 15 | ![](../../assets/1.5.jpg) 16 | **图1.5 当您需要支持不断增加的工作负载时,垂直扩展模型将添加硬件资源给计算节点,而水平扩展模型将增加更多计算节点。** 17 |
18 | 19 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.2-Loose-coupling.md: -------------------------------------------------------------------------------- 1 | ### 1.3.2 松耦合 2 | 3 | 松耦合是系统的一个基本特性,即系统各部分之间尽可能少的相互依赖。其目标是可以独立地开发每一个部分,以便于某部分的修改,不影响其他部分。 4 | 5 | 几十年来,`耦合` 及其孪生概念 `内聚` 在面向对象的软件工程中起着至关重要的作用。将系统分解为模块(模块化),最小化对其他部分依赖(松耦合),并对代码的修改封闭(高内聚),是一种很好的设计实践。。根据架构风格的不同,可以对整体或对独立服务(例如,微服务)进行建模。不管怎样,您都应该瞄准目标,按松散耦合和高内聚性进行模块化。 6 | 7 | Parnas 指出了模块化的三个好处: 8 | * **可管理性**。由于每个模块都是松散耦合的,因此团队应该可以减少开发的时间,因为与其他团队进行大量协调和沟通就不需要了。 9 | * **产品灵活性**。每个模块应独立于其他模块进行演变,形成了一个非常灵活的系统。 10 | * **可理解性**。不必从整体上研究系统来理解一个特定的模块,而是一次一个模块的研究。 11 | 12 | 上述好处通常都是与微服务相关的好处。事实上您不需要用微服务来实现它们。在过去几年中,许多组织决定从单体服务迁移到微服务。他们中的一些人因为缺乏适当的模块化经验而失败了。一个单体应用,由紧密耦合的组件组成整体,迁移后会产生一个紧密耦合、无内聚性的微服务系统。有时称为`分布式单体`。如果您告诉我,这不是一个好名字,因为按定义来说它意味着,这是由紧密耦合的非内聚组件组成的。这不全对。是何种架构都无关紧要:糟糕的设计就是糟糕的设计。事实上,我喜欢 `Simon Brown` 提出的`模块化单体`术语,旨在提高人们的认识,就是单体应用也可以优化成松散耦合和高内聚,最终单体和微服务都混在了一起,成为“大泥球”。 13 | 14 | 在本书中,我将介绍一些应用程序中实施松耦合的技术。特别是我将采用基于服务的体系结构,重点关注服务构建。服务力求高内聚,与其他服务的依赖要最小,服务之间使用清晰的接口相互通信。 15 | 16 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.3-Resilience.md: -------------------------------------------------------------------------------- 1 | ### 1.3.3 韧性 2 | 3 | 如果系统即使在出现故障或环境发生变化的情况下也能提供服务,则系统是有韧性的。韧性是“面对故障或挑战性操作,软硬件网络仍能提供和维持一个可接受的服务水平”。 4 | 5 | 云原生应用程序在动态环境中运行,其中所有内容都在不断变化,并且故障可能随时会发生。这是无法阻止的。过去,我们习惯于把变化和故障作为异常。但对于高度分布式的系统,如云原生系统,变化不是异常:它们是常态。 6 | 7 | 您的目标应该是:无论基础架构或软件中是否出现故障,都要确保您的应用程序可用。 8 | 9 | 在讨论韧性时,有必要定义三个基本概念:故障、错误和失效。 10 | * **故障(Fault)**。是软件或基础设施中会产生错误内部状态的缺陷。示例:方法调用返回空值,即使其规范要求返回非 null 值。 11 | * **错误(Error)**。是指系统的预期行为与实际行为的差异。示例:由于上面的错误,将引发抛出 NullPointerException。 12 | * **失效(Failure)**。当触发故障并导致错误时,可能会发生失效,导致系统没有响应,无法按照其规范运行。示例:如果未捕获 NullPointerException,则错误会引发失效,系统将对任何请求返回 500 响应。 13 | 14 | 故障可能会变成错误,这可能会引发失效,因此您应该将应用程序设计为能够 `容错(fault tolerant)`。韧性的一个重要部分是确保失效不会波及到其他系统组件,而是使它保持隔离。您还需要这个系统能够 `自我修复(self-repairing)`,而云模型实际上可以实现这一点。 15 | 16 | 在本书中,我将向您展示一些容错技巧,防止故障传播到系统的其他部分。例如,您将利用 Spring Cloud Circuit Breaker 和 Resilience4J 来实现断路器、重试和冗余。 17 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.4-Observability.md: -------------------------------------------------------------------------------- 1 | ### 1.3.4 可观测性 2 | 3 | 可观测性是来自控制理论的一个特性。考察一个系统时,可观察性是一种通过衡量外部输出,来推断其内部状态的方法。在软件工程中,系统是一个单一的应用程序或一个分布式系统。整体外部输出可以是度量、日志和跟踪等数据。图 1.6 显示了可观测性是如何工作的。 4 | 5 | ![](../../assets/1.6.jpg) 6 | 7 | **图 1.6 可观测性指的是通过外部输出推断应用程序的内部状态。可管理性是指通过外部输入来改变内部状态和输出。在这两种情况下,应用程序本身不会更改。它是不可变的。**
8 | 9 | Twitter 的可观测性工程团队确定了可观测性的四大支柱: 10 | * **监测**。监视是关于测量应用程序的某些特定方面,以获得有关其整体健康状况的信息并识别故障。在本书中,您将利用 Spring Boot Actuator 的监控功能,并将 Prometheus 与 Spring 集成来导出有关应用程序的相关度量信息。 11 | * **警报/可视化**。收集有关系统状态的数据只有在使用时才有用。在监测到应用程序发现故障时,应触发警报,并且应该采取一些措施来处理它。定制监控大盘用于可视化收集的数据,并将其绘制在相关图表中,旨在提供系统运行的良好视图。在本书中,您将了解如何使用 Grafana 可视化从云原生应用程序收集的数据。 12 | * **分布式系统跟踪基础设施**。在分布式系统中,仅仅跟踪每个子系统的行为是不够的。跟踪数据流经的不同子系统非常重要。在本书中,您将使用 Spring Cloud Sleuth 进行分布式链路跟踪,并整合 Spring 与 Jaeger,以对跟踪数据进行可视化。 13 | * **日志聚合/分析**。跟踪应用程序中的主要事件至关重要,可以推断软件的行为并在出现问题时进行调试。在云原生系统中,应聚合和收集日志,以便更好地了解系统行为,才有可能进行分析,从数据中挖掘信息。在本书中,我将较多地讨论日志。您将学习使用 EFK 技术栈(Elastic、Fluentd、Kibana)来收集和可视化日志。 14 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.5-Manageability.md: -------------------------------------------------------------------------------- 1 | ### 1.3.5 可管理性 2 | 3 | 在控制理论中,可观测性的对偶概念是可控性。可管理性代表了外部输入改变系统状态或有限时间间隔内输出的能力。这个概念引出云原生的最后一个主要特性:可管理性。 4 | 5 | 再次借鉴控制理论,我们可以说可管理性是一种衡量外部输入改变系统状态或系统输出有多容易的方法。更直白一点来说,它是一种无需更改代码即可修改应用程序行为的能力。不要与可维护性相混淆,可维护性是一个衡量从内部高效地更改系统,也就是说通过更改其代码有多容易的指标。图形 1.6 展示了可管理性是如何工作的。 6 | 7 | 可管理性的一个方面是部署和更新应用程序,同时保持整个系统是启用的、持续运行的。另一个因素是配置,整本中将深入讨论它。您希望使云原生应用程序可配置,以便在不更改代码和构建新版本的情况下修改其行为。进行配置修改很常见,如修改数据源 URL、服务凭据和证书。比如,根据环境的不同,您可以使用不同的数据源:一个用于开发,一个用于测试,一个用于生产。还可以使用其他类型的配置,用于决定是否应在运行时启用特定功能的标志。 8 | 9 | 可管理性不仅关系到变更本身,还关系到您应用这一修改是否轻松、高效。云原生系统非常复杂,因此设计应用程序可以适应功能、环境和安全方面不断变化的需求非常重要。考虑到复杂性,您应该致力于尽可能多地通过自动化进行管理,这让我们进入云原生的三个 P 中的最后一个:实践(Practices)。 10 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.3 云原生应用的特性 2 | 3 | 场景已经设置好了:在云中。您应该如何设计应用程序以充分利用它的特点呢?CNCF 确定了云原生应用程序应该有的五个主要特性。就其本身而言,其想法是云原生是一种构建和运行应用程序,以展示出这些特性的方法论。Cornelia Davis 总结道,“云原生软件是由您的计算方式,而不是由在什么地方计算来决定的”。换句话说,云表示的是何处,云原生表示是怎么实现。 4 | 5 | 前面已经讲述了表示何处的部分:云。现在,让我们继续探索如何进行实现。做为一个快速参考,图 1.4 列出了相关特性和简短说明。 6 | 7 | ![](../../assets/1.4.jpg) 8 | **图 1.4 云原生应用程序的主要属性是可伸缩性、松耦合、弹性、可管理性和可观察性。 ** 9 | 10 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.1-Automation.md: -------------------------------------------------------------------------------- 1 | ### 1.4.1 自动化 2 | 3 | 自动化是云原生的核心原则。其思想是将重复的手动任务自动化,以加快云原生应用程序的交付和部署。可以自动化执行许多不同的任务,从构建应用程序到部署应用程序,从基础架构资源调配到配置管理。自动化最重要的优点是它使流程和任务可重复,整体系统更稳定可靠。手动执行一项任务容易出错,而且成本较高。通过使其自动化,您可以更可靠和更高效地得到结果。 4 | 5 | 云计算模型的特点是,提供的计算资源都在自动化的自助服务模式中,并具有弹性地增加或减少计算资源的能力。云基础设施的两大自动化类别:资源调配和配置管理。我们把它们称为: `架构即代码(infrastructure as code)` 和 `配置即代码(configuration as code)`。 6 | 7 | Martin Fowler 将 `架构即代码` 定义为:“像任何软件系统的代码一样,通过源代码定义计算和网络基础设施的方法”。 8 | 9 | 云服务商提供方便的 API 来创建和配置服务器、网络和存储。通过使用 `Terraform` 之类的工具自动化这些任务,将代码置于源代码控制中,使用与应用程序开发相同的测试和交付实践,您可以获得更多可靠的基础设施,可再生、更高效、风险更低。一个简单的例子:一个自动化的任务可能是创建一个新的虚拟机,它有 8 个 CPU,64GB 内存和 Ubuntu 20.04 LTS 操作系统。 10 | 11 | 配置计算资源后,您可以管理它们并自动配置它们。套用前面的定义,`配置即代码` 是像任何软件系统的代码那样,通过代码定义配置资源。 12 | 13 | 使用 `Ansible` 等工具,您可以用声明的方式编写服务器或网络的配置。例如,在上面设置 Ubuntu 服务器之后,您可以自动完成安装 Java 运行时环境(JRE)16.0.1、Python 3.7、在防火墙打开端口 8080 和 8443。这也适用于应用程序的配置。 14 | 15 | 通过自动化所有任务,来处理与基础架构资源调配和配置管理相关的工作,您可以避免不稳定、不可靠的 `雪花服务器(snowflake server)`(每一片雪花都是独一无二的,参考 [SnowflakeServer](https://martinfowler.com/bliki/SnowflakeServer.html) )。如果手动配置、管理每个服务器,结果将是一个独一无二的 `雪花`:一个脆弱的、独特的服务器,无法复制,任何更改都有风险。自动化有助于避免这种情况,有利于生成 `凤凰服务器(phoenix servers)`(凤凰涅槃,浴火重生,参考 [PhoenixServer](https://martinfowler.com/bliki/PhoenixServer.html)):在这些服务器上执行的所有任务都是自动化的,每个更改都可以在源服务器中跟踪控制、降低风险,并且每个设置都是可复制的。将这一概念发挥到极致,实现所谓的 `不可变服务器`(参考 [ImmutableServer](https://martinfowler.com/bliki/ImmutableServer.html)),CNCF 在其云原生中也提到了这一点,来定义不可变的基础设施。 16 | 17 | 初始资源调配和配置后,`不可变服务器` 不再更改:它们是不变的。如果需要任何更改,则修改其定代码并提交。一个新的服务器最终根据新代码进行设置和配置,而上一个服务器被销毁。 18 | 19 | 在下一节中,我将讨论构建和部署应用程序的自动化。 20 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.2-Continuous-delivery.md: -------------------------------------------------------------------------------- 1 | # 1.4.2 持续交付 2 | 3 | CNCF 指出,云原生技术应与强大的自动化相结合,以经常进行影响较大的更改。其中一部分是通过持续交付提供的。 4 | 5 | 持续交付是“一种软件开发规程,让您在的软件可以随时投入生产的方式”。 6 | 7 | 通过持续交付,团队在短周期内实现功能,确保软件可在任何时间可靠释放。 8 | 9 | `持续集成`(CI)是持续交付的先决条件,包括集成提交更改后的软件,构建它,并最终在类生产环境进行自动化测试。此过程应自动化,并由 CI 服务器执行。这个流程中涉及的步骤被声明为 `流水线(pipelines)`。 10 | 11 | `持续交付`(CD)通过在流水线中包含额外步骤而构建在 CI 之上。之后通过运行自动化测试,软件被打包,发布版本被构建并部署到 12 | 类生产环境,以验证其是否有效。自动化流水在连续生产中的应用交付称为 `部署流水线`。 13 | 14 | 由于持续交付的基础是持续集成,我们通常将其称为 CI/CD。在本书中,您将构建部署流水线以保持发布分支处于良好状态。最后,您将使用它将应用程序自动部署到 Kubernetes 集群进行测试,然后发布到生产。 15 | 16 | 有时,人们会把 `持续交付` 与 `持续部署` 相混淆。前一种方法确保每次更改后,软件都处于可以部署的状态。何时真正做到这一点是一个业务决策。而对于连续部署,您可以在一个 CI/CD 流水线的最后添加一步,在每次发布后自动在生产中部署新版本。 17 | 18 | `持续交付` 不仅仅是工具。这是一个规程,涉及文化和组织中的结构变化。设置自动化流水线以测试和交付您的应用程序,并不意味着您在进行持续交付。这就引出了下一个话题,也通常被误认为只是工具。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.3-DevOps.md: -------------------------------------------------------------------------------- 1 | # 1.4.3 DevOps 2 | 3 | DevOps 是另一个流行语,但有时也被误解了。当转向云原生时,这是一个需要掌握的重要概念。 4 | 5 | DevOps 的起源很奇特。如果您有兴趣,我建议您在 YouTube 上看看 Ken Mugrage 的演讲。其中一个令人好奇的方面是,这部电影的创作者决定不提供这个概念的定义。结果是不同的人有不同的理解,我们最终使用 DevOps 表示了很多不同的东西。 6 | 7 | 在 DevOps 的所有定义中,我找到了 Ken Mugrage 提出的定义。他强调了 DevOps 的真正含义,其中包含大量信息也很有趣。 8 | 9 | *一种文化,在这种文化中,人们不分头衔或背景,共同规划、开发、部署和运维一个系统。* 10 | 11 | 因此,DevOps 是一种文化,它是关于为了一个共同的目标而共同努力的。开发人员、测试人员、运维人员/运维工程师和其他人员,无论其职称或背景如何,都会参与,一起把想法带到生产中。 12 | 13 | 这意味着各自为战的终结,功能团队、QA 团队和运维团队之间不再有隔阂。DevOps 通常被认为是敏捷的自然延续,这也是小团队经常使用的概念,来向客户提供价值。亚马逊首席技术官 Werner Vogels 在 2006 年的一句著名的话,更简洁的描述了 DevOps,那时 DevOps 还未成型:“您建立它,您运行它”。 14 | 15 | 在定义了什么是 DevOps 之后,让我们简要介绍一下它不是什么。 16 | 17 | * _DevOps 并不意味着没有运维_。一个常见的错误是认为开发人员负责运维,这里运维人员的角色消失了。这是一种合作。一个团队包括这两种角色,有助于提高团队的整体技能,将创意变成产品。 18 | * _DevOps 不是一个工具_。像 Docker、Ansible、Splunk 和 Prometheus 这样的工具通常是称为 DevOps 工具,但这是错误的。DevOps 是一种文化。您不会因为使用这些工具而成为 DevOps 组织。换句话说,DevOps 不是产品,而是相关促成者的工具。 19 | * _DevOps 不是自动化_。即使自动化是 DevOps 的重要组成部分,但不是 DevOps 的定义。DevOps 是关于开发者和运维人员从构思到实践的合作,同时可能自动化一些流程,如 `持续交付`。 20 | * _DevOps 不是一个角色_。如果我们认为 DevOps 是一种文化,一种观念,很难理解 DevOps 角色。然而,对 DevOps 工程师的要求越来越高。通常,当招聘人员寻找 DevOps 工程师时,他们需要的技能包括熟练使用自动化工具、脚本和 IT 系统。 21 | * _DevOps 不是一个团队_。没有充分了解上述风险的组织,最终会保持与以前相同的思路。只不过是这样变化:添加一个 DevOps 筒仓(silo, 参考 [Analysing the DevOps Silo](https://www.thoughtworks.com/insights/blog/analysing-devops-silo))替换 Ops 筒仓或什么别的筒仓。 22 | 23 | 开发人员和运维人员之间的协作,在云原生中至关重要。您可能已经注意到,设计和构建云原生应用程序,需要您始终记住您将在哪里部署这些应用程序:云端。与运维人员合作允许开发人员设计和制造更高质量的产品。它叫 DevOps。但是让我们记住,这个定义不仅仅适用于开发人员和运维人员。相反,它泛指各类人,不分头衔或背景。这意味着合作也在其他角色之间进行,如测试人员和安全专家。他们共同负责整个产品生命周期的工作。有了 DevOps 思维,您可以真正实现 CNCF 定义的云原生应用目标:“允许工程师用最少的劳动,进行频繁的和可预测的重大功能更新”。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.4 支持云原生的文化和实践 2 | 3 | 在本节中,我将重点介绍 CNCF 给出的云原生定义的最后一句话:“与强大的自动化相结合,它们允许工程师用最少的劳动,进行频繁的和可预测的重大功能更新。” 我将讨论三个概念:自动化、持续交付和 DevOps,如图1.7 所示。 4 | 5 | ![](../../assets/1.7.jpg) 6 | **图 1.7 云原生开发的文化和实践。**
7 | 8 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.1-Speed.md: -------------------------------------------------------------------------------- 1 | ### 1.5.1 速度 2 | 3 | 能够更快地交付软件是当今企业的一个基本目标。将想法投入生产越快越好,较缩的上市时间是关键的竞争优势。能否在正确的时间,将正确的想法投入生产,就是成功和失败的差别。 4 | 5 | 客户希望实现越来越多的功能或修复 bug,他们希望立刻完成。他们不会乐意为我们的下一个软件版本等待六个月。他们的期望值不断增加,您需要一种方法来跟上这个节奏。一切都是为了给客户提供价值,并确保他们对结果感到满意。否则,您的公司将无法在激烈的竞争中生存。 6 | 7 | 更快、更频繁地交付不仅关系到竞争,还关系到客户给定的最后期限,也和缩短反馈周期有关。频繁和小规模的发布,意味着您可以尽快得到客户的反馈。较短的反馈周期,会让您发布的新功能有较低的风险。不是要花几个月的时间实现完美的功能,您可以很快将其发布,从客户那里获得反馈,然后调整它以符合客户的期望。此外,较小的版本包含较少的更改,因此更能减少可能出现故障的数量。 8 | 9 | 灵活性也是必需的,因为客户希望您的软件能够不断发展。例如,它应该足够灵活以支持新类型的客户端。如今,我们日常生活中的物品,越来越多的连接到互联网。想想各种各样的手机和物联网系统。您希望对任何未来的扩展和终端类型保持开放,以新的方式提供服务。 10 | 11 | 传统的软件开发方法都无法实现这些目标,它们总是重大发布、灵活性小和过长的发布周期。云原生方法,结合自动化任务、持续交付流水线和 DevOps 实践,有助于加快业务发展并缩短上市时间。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.2-Resilience.md: -------------------------------------------------------------------------------- 1 | ### 1.5.2 韧性 2 | 3 | 一切都在变化,失效总是在发生。我们试图预测失效,并将其视为异常的时代已经一去不复返了。正如我前面提到的,变化也不是异常。这是常规。 4 | 5 | 无论基础设施或软件是否出现故障,您的目标都是确保系统的可用性和可靠性。您希望继续为您的用户提供服务,即使是在降级模式下运行。 6 | 7 | 客户希望软件全天候可用,并在出现新功能后立即升级。停机或故障可能导致直接的金钱损失和客户不满。甚至会影响一个人的声誉,导致组织本身在未来市场上的机会受到损害。 8 | 9 | 即使发生错误,有韧性的系统仍能继续提供服务。要保证可用性,您需要在故障出现时采取适当措施来应对故障,处理它们,并确保整个系统仍能向用户提供服务。任何处理故障和升级等任务所需的操作都只不需要停机。客户期望如此。 10 | 11 | 没有任何硬件或软件是百分百可靠和可用的,因此您需要韧性。云原生应用程序利用底层云基础设施,设计为在面对变化时具有韧性。如果保持始终可用、安全和有韧性是您的需求,那么云原生对您来说是一个很好的选择。软件的韧性系统,反过来,可以提高速度:越稳定的系统,您可以更频繁地、更安全地发布新功能。 12 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.3-Scale.md: -------------------------------------------------------------------------------- 1 | ### 1.5.3 规模 2 | 3 | 弹性是指能够根据负载进行扩展。您可以缩放一个弹性系统,确保为所有客户提供适当的服务级别。负载比平时要大时,您需要启动更多的服务实例来支持额外的负载。当发生了一些极端可怕的状况时,服务失败了,您需要能够启动新实例替换它们。 4 | 5 | 问题是,预测未来会发生什么是困难的。构建可伸缩的应用程序还不够。您需要它们能够动态缩放。每当有高负载时,您的系统应该动态、快速、轻松地扩展。随着时间的推移,当高峰来临时它应该会再次扩大。 6 | 7 | 如果您的业务需要快速、高效地适应新客户,或者需要灵活性来支持新类型的客户端(这会增加服务器上的工作负载),那么云的本质可以为您提供所需的所有弹性,与云原生相结合的应用程序可以按配置进行扩展。 8 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.4-Cost.md: -------------------------------------------------------------------------------- 1 | # 1.5.4 成本 2 | 3 | 作为一名软件开发人员,您可能不会直接与金钱打交道,但设计解决方案时考虑成本,也您的责任。凭借弹性和按需支付的策略,云计算模型有助于优化 IT 基础设施成本。不再总是开着基础设施,而是在需要时提供资源,支付实际使用费用,然后当您不再需要它们时,销毁它们。 4 | 5 | 最重要的是,采用云原生方法将导致进一步的成本优化。云原生应用程序被设计为是可伸缩的,以便它们可以利用云的弹性,因此与生产中的宕机和硬件故障相关的成本会降低。由于松散耦合,这能使团队效率提高,能有更快地上市时间,显著提高竞争优势。还有很多其他好处不再赘述。 6 | 7 | >**上云的隐藏成本** 8 | > 9 | >在决定迁移到云之前,必须考虑其他的成本。一方面,您可以按如上所述优化成本。另一方面,您应该考虑迁移的成本和它的后果。迁移到云需要具备特定能力,但员工可能还不具有。这意味着要投资进行培训,或许还需要雇佣专业人士协助迁移到云。取决于所选的解决方案,还可能需要承担一些额外的责任,这反过来要求要有特定技能(例如,处理云安全问题)。还有其他需要考虑的因素,如迁移期间的业务中断、重新培训终端用户、更新文档和支持材料等等。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.5 上云是最好的选择吗? 2 | 3 | 我们行业中最大的错误之一,就是仅仅因为技术或方法是新的、每个人都在谈论它,就决定采用它。将的巨大的单体应用移植成微服务,最终导致灾难性失败的故事层出不穷。我已经解释了云和云原生应用程序的特性,这些应该能给您提供一些指引。如果您的系统不需要这些特性,也没有这些需要解决的相关问题,很可能“上云”对您的项目来说,并不是一个好的选择。 4 | 5 | 作为技术专家,很容易被最新、最时尚、最闪亮的技术所吸引。重点就是要弄清楚一种特定的技术或方法是否能解决您的问题。我们将想法变成软件,交付给客户,并为他们提供一些价值,这是我们的最终目标。如果某项技术或方法,能帮助您为客户提供更多价值,那么您应该考虑一下。如果它不会给客户带来更多价值,而您决定仍要这样做,您很可能会发现成本高、问题多,最后以失败告终。 6 | 7 | 什么时候上云?为什么公司都开始走上云这条路?走这条路最主要的目标如图 1.8 所示,云原生的主要目标是速度、规模、韧性、灵活性和成本。如果您的业务愿景包括这些目标,并且必须面对这些云技术试图解决的问题,那么考虑迁移到云,采用云原生方法是很好的。否则,最好仍保持现状。例如,如果您的公司在维护某个单体应用程序,而该服务不会再进一步扩展,而且在过去的几十年里一直运行良好,这就没有很好的理由将其迁移到云端,更不用说将其转变为一个新的应用程序以成为云原生应用了。 8 | 9 | ![](../../assets/1.8.jpg) 10 | **图 1.8 “云原生”的目标是实现速度、韧性、规模和成本优化。** 11 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.1-Containers.md: -------------------------------------------------------------------------------- 1 | ### 1.6.1 容器 2 | 3 | 想象一下,您加入了一个团队,开始开发一个应用程序。您要做的第一件事就是遵循开发指南,将自己的开发环境设置成与同事类似的环境。您开发一个新特性,然后在质量测试(QA)环境中测试它。一旦验证通过,应用程序就可以准备部署,再经过一些额外的测试,就可以上生产。该应用程序是为在特定的环境中运行而构建的,因此必须使所有涉及的环境尽可能相似。您要怎么保证这一点呢?这就是容器的价值所在。 4 | 5 | 在使用容器之前,您将依赖虚拟机来保证环境的可复制性、隔离和可配置性。虚拟化通过利用虚拟机监控程序进行硬件抽象,使其能够在同一台物理机上运行多个操作系统,以一种相互隔离的方式。虚拟机监控程序将直接在机器硬件上运行(类型 1 )或主机操作系统上运行(类型 2 )。 6 | 7 | 另一方面,OS 容器是一个轻量级的可执行包,包含所有需要在内部运行应用程序的内容。容器共享同一内核:无需完全引导操作系统来添加新的隔离上下文。在 Linux 上,这可以利用 Linux 内核提供的功能。包括: 8 | 9 | * _名称空间(namespaces)_ 用于在进程之间划分资源,以便每个进程(或进程组)只能看到机器上可用资源的子集; 10 | * _控制组(cgroups)_ 用于控制和限制进程(或进程组)的资源使用。 11 | 12 | >仅使用虚拟化时,硬件是共享的,而容器也共享相同的操作系统内核。无论如何,两者都提供了用于隔离运行软件的计算环境,即使隔离的程度是不一样的。 13 | 14 | 图 1.10 显示了虚拟化和容器技术之间的区别。 15 | 16 | ![](../../assets/1.10.jpg) 17 | 18 | **图 1.10 虚拟化和容器技术在隔离上下文中共享的内容不同。虚拟机只共享硬件。容器也共享操作系统内核。后者更轻、更便携。**
19 | 20 | 为什么容器在云原生应用中如此流行?传统上,您必须在虚拟机上安装并维护 JRE 和中间件,以使应用程序运行起来。而容器可以在几乎任何计算环境中可靠运行,独立于应用程序、其依赖项或中间件。不管是哪种应用程序,用哪种语言编写,或使用哪种库。从外部看,所有容器都有一个相似的形状,就像用于运输的集装箱一样。 21 | 22 | 因此,容器实现了灵活性、跨不同环境的可移植性和可重复部署性。由于轻量,对资源的要求较低,它们非常适合在云中运行,因为实例都是一次性的,会经常快速地扩缩。相比之下,构建和销毁虚拟机要昂贵得多,而且费时。 23 | 24 | >**容器!到处都是容器!** 25 | > 26 | >容器(Container) 是一个可以表示不同事物的词,这取决于文本的上下文。有时候模棱两可会产生一些混乱,所以让我们看看它在不同的语境中意味着什么。 27 | >* 操作系统。操作系统容器是一个与系统其余部分隔离的环境,是在系统中运行一个或多个进程的方法。在本书中,我们将重点介绍 Linux 容器,但请注意 Windows 容器也存在。 28 | >* Docker。Docker 容器是 Linux 容器的实现,开放容器计划(OCI)已将其标准化。 29 | >* Spring。Spring 容器是指应用程序上下文,其中属性和其他应用程序资源被管理和执行。 30 | >* Servlet。利用 Java Servlet API,Servlet 容器为 web 应用程序提供运行时。如 Tomcat 服务器的 Catalina 组件,就是 Servlet 容器的一个示例。 31 | 32 | 虚拟化和容器并不是相互排斥的。实际上,您可以在云中同时使用它们:在虚拟机组成的基础架构中运行容器。IaaS 模型(基础架构即服务)提供了一个虚拟化层,可以用于引导新的虚拟机。最重要的是,您可以直接运行您的容器。 33 | 34 | 在开发或执行一些早期测试时,应用程序通常由在同一台机器上运行的不同容器组成。但您很快就会发现,需要管理的容器太多,实在太复杂了。尤其是当您为扩展性而开始复制容器时,将容器分布到不同的机器上。那时,您就应该开始依赖 CaaS 模型(容器即服务)提供更高级别的抽象了。它提供计算机集群中部署和管理容器的功能。请注意,在此场景中,仍然有一个虚拟化层。 35 | 36 | 即使在使用诸如 Heroku 或 Cloud Foundry 之类的 PaaS 平台时,也会涉及容器。您在这些平台上部署应用程序,只需提供 JAR 工件,平台处理 Java 运行时环境、中间件、操作系统和任何需要的依赖项。在幕后,他们用所有这些组件构建了一个容器,并最终运行了您的 JAR。所不同的是,不再由您负责建造一个容器,而是平台本身为您完成了这一任务。一方面,这很方便,开发人员的责任少了。另一方面,您放弃了对运行时和中间件的控制,只能使用供应商固定提供的中间件类型。 37 | 38 | 在这本书中,您将学习如何使用 Cloud Native Buildpacks 对 Spring 应用程序进行容器化,您将使用 Docker 在本地环境中运行它们。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.2-Orchestration.md: -------------------------------------------------------------------------------- 1 | ### 1.6.2 编排 2 | 3 | 现在您决定使用容器了,真是太好了!您可以依靠容器的可移植性,将它们部署到提供容器运行时的任何基础架构中。实现了可再现性,所以将容器从开发环境转移到暂存环境,再转移到生产时都很方便。您可以快速缩放,因为它们是如此轻量。还为您的应用程序提供了高可用性,所以可以快速地对它们进行更新。您已经完全准备好将它们用于您的下一个云原生系统了,是吗? 4 | 5 | 在一台机器上配置和管理容器非常简单。但是当您开始处理数十个或数百个容器,这些容器被缩放并部署在多台机器上,您还需要别的东西。 6 | 7 | 当我们从虚拟服务器(IaaS 模型)转移到容器集群(CaaS 模型)时,我们还需要更新我们的观念。在 IaaS 中,我们关注单个计算节点,就是个虚拟服务器。在 CaaS 中,底层基础设施是抽象的,我们关注的是节点集群。有了 CaaS 解决方案提供的新视角,部署目标将不再是一台机器,而是一个集群。像 Kubernetes 这样的 CaaS 平台,为云原生环境中我们所关心的这些问题,提供了解决方案:跨集群编排容器。这两种不同的拓扑如图 1.11 所示。 8 | 9 | ![](../../assets/1.11.jpg) 10 | **图 1.11 容器的部署目标是一台机器,而对于编排器来说,它是一个集群。**
11 | 12 | 容器编排可帮助您自动化许多不同的任务: 13 | * 管理集群,必要时启动和关闭机器; 14 | * 将集群中的容器进行调度并部署,直到满足容器对 CPU 和内存的要求; 15 | * 动态扩展容器实例,利用运行状况监测实现高可用性和韧性; 16 | * 为容器建立相互通信的网络,定义路由、服务发现和负载平衡; 17 | * 向因特网公开服务,建立端口和网络; 18 | * 根据特定标准向容器分配资源; 19 | * 配置容器中运行的应用程序; 20 | * 确保安全并强制执行访问控制策略。 21 | 22 | 指令编排工具是以声明方式完成的,例如,通过 YAML 文件。按照特定工具定义的格式和语言,您通常描述希望实现的状态:希望在集群中部署 3 个 web 应用程序容器副本、向 Internet 公开其服务。 23 | 24 | 容器编排器可以使用 Kubernetes、Docker Swarm 或 Apache Mesos。在这本书中,您将学习如何使用 Kubernetes 为 Spring 编排应用容器。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.3-Serverless.md: -------------------------------------------------------------------------------- 1 | ### 1.6.3 无服务器架构 2 | 3 | 在从虚拟机移到容器之后,云提供的抽象可以进一步提高:这就是无服务器模式。用这个计算模型,您只需构建应用程序。云服务商负责设置应用程序使用的基础架构和服务,包括服务器、数据库和其他支持服务。 4 | 5 | >这个名字有一定误导性:肯定有服务器,只不过不是您在管理它或在其上部署应用程序。 6 | 7 | 像 AWS Lambda 和 Azure Functions 这样的 FaaS 平台就是无服务器模式的例子。在使用这些平台时,您只需要提供业务逻辑函数。平台将设置运行该函数所需的整个基础设施。函数是按使用次数计算成本的。 8 | 9 | 如果您正在为事件驱动应用程序使用函数,则它们将仅在发生事件时运行。事件可以是外部的,也可以由另一个函数生成。例如,当有消息添加到队列中时,函数可能被触发,然后执行函数,最后退出执行。当无需处理时,平台会关闭所有相关资源。所以您可以只为实际使用付费。而在其他云拓扑,如 CaaS 或 PaaS,始终有一台服务器在全天候运行。与传统的系统相比,您可以利用动态伸缩性来减少资源数量,只在特定时间提供服务。无服务器模型仅在必要时才提供资源,如果没有要进行处理的,一切都将关闭。 10 | 11 | 无服务器模式不仅包括 FaaS,还包括其他技术。例如 Knative 是一种在 Kubernetes 之上构建无服务器平台的工具,可以将应用程序作为容器和函数运行。 12 | 13 | 除了成本优化之外,无服务器技术还将一些额外的责任从应用转到平台。这可能是一个优势,因为它允许开发人员集中精力,只需关心业务逻辑。您也要认识到,这种情况下必须处理好供应商锁定的问题。每个 FaaS,以及通常的无服务器平台,都有自己的功能和特性 API。一旦开始为特定平台编写函数,就无法轻松地将其移植另一个平台。使用 FaaS 比使用任何其他方法,都更能体现为便利而放弃责任和控制。 -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.6 云原生拓扑 2 | 3 | 我对云原生的解释没有涉及具体的技术或架构。CNCF 在定义中提到了一些,比如容器和微服务。但正如我之前强调的,这些只是示例。创建云原生应用程序并不强制要求您使用 Docker 容器。考虑无服务器模型或 PaaS 解决方案,为 AWS Lambda 编写函数或将应用程序部署到 Heroku 都不需要构建容器,但这些都被归类为云原生。 4 | 5 | 在本节中,我将描述一些常见的云原生拓扑。首先,我将介绍容器和编排的概念,后续讨论 Docker 和 Kubernetes 时将进一步探讨这些概念。然后,我将介绍无服务器技术和函数的主题(FaaS)。在本书中,我不重点介绍 FaaS 模型,但我将介绍如何使用 Spring Native 和 Spring Cloud Function 构建无服务器应用程序。 6 | 7 | 图 1.9 突出显示了我将在本节中介绍的概念。 8 | 9 | ![](../../assets/1.9.jpg) 10 | **图 1.9 主要的云原生计算模型是容器(由编排器管理)和无服务器模型。** -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/1.7.1-From-multi-tiered-to-microservice-architectures-and-beyond.md: -------------------------------------------------------------------------------- 1 | ### 1.7.1 从分层到微服务到更高级别 2 | 3 | IT 基础设施始终影响着软件的架构设计和运行方式。起初,我们在大型机上部署单个组件组成的单体应用程序。当互联网和个人电脑变得流行时,我们开始根据 `客户端/服务器模式` 设计应用程序。这是一个分层的体系结构。这种模式被广泛用于桌面和 web 应用程序,代码分解为表示层、业务层和数据层。 4 | 5 | 随着应用程序复杂性的增加和对敏捷性的需求,人们开始探索进一步对代码进行分解的方法。一种新的架构风格进入历史舞台:微服务。近几年来,这种架构风格越来越流行,许多公司决定根据这种新风格重构他们的应用程序。微服务与单体应用程序的异同如图 1.13 所示。 6 | 7 | ![](../../assets/1.13.jpg) 8 | 9 | **图 1.13 单体式与微服务。单体结构是多层的。微服务是由可以独立部署的不同组件组成。**
10 | 11 | 主要区别在于应用程序的分解方式。单体应用程序分为 3 层。相反,基于微服务的应用程序与多个组件关联,每个组件只实现一项功能。还有很多模式被提出,可将单体应用分解为微服务,以处理多个组件而不是一个组件的复杂性。 12 | 13 | >这本书不是关于微服务的。因此,我不会进行更多详述。如果您是对这个话题感兴趣,Manning 出版社有几本关于微服务的书。比如 Chris Richardson 的 “Microservice Patterns”,还有 John Carnell 和 Illary Huaylupo Sanchez 合著的 “Spring Microservices”。如果您不熟悉微服务,不用担心,阅读本书并不要求您必须掌握这这方面的知识。 14 | 15 | 16 | 在经历了多年成功和失败的迁移之后,在开发人员社区,展开了对这种流行的架构风格的激烈讨论。一些开发者建议切换到 `微服务`以减少组件的数量,从而降低管理它们的复杂性。其他人则提出了 `城堡` ([citadel](https://blog.appsignal.com/2020/04/08/the-citadel-architecture-at-appsignal.html)) 架构风格,由一个中心的单体,以及环绕的微服务组成。尽管如此,其他人仍在鼓吹以模块化单体的形式回归单体应用。 17 | 18 | 最后,我认为重要的是选择一个能够支撑我们的业务,为客户提供价值的架构。这也我们开发应用程序的初衷。 19 | 20 | 每种架构风格都有其用武之地。世上没有银弹或适用一切的解决方案。大多数与微服务相关的负面体验都是由其他问题导致的,例如错误的代码模块化。单体应用与微服务之间不应水火不容。 21 | 22 | 在本书中,我有兴趣向您展示如何使用 Spring 构建云原生应用程序,并将其作为 Docker 容器部署到 Kubernetes。云原生应用程序是分布式的,就像微服务一样。您将发现通常讨论的微服务主题,实际上属于分布式系统,例如:路由和服务发现。云原生应用程序是松散耦合的,这是微服务的一个特性。 23 | 24 | 即使存在很多类似的地方,理解云原生应用程序与微服务不完全一样,也是至关重要的。您可以使用微服务风格来实现云原生应用。事实上,许多开发人员都是这样做的。但这不是一个硬性要求。在这本书中,我将使用可能称之为 `基于服务` 的架构。也许这不是一个吸引人的名字,但这对我们来说已经足够了。我们开发服务,它们可以是任意大小,并且它们可以根据不同的原则进行逻辑封装。以后您想要开发什么样的服务都行,只要根据组织和业务需求来设计。 25 | 26 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/1.7.2-Service-based-architecture-for-cloud-native-applications.md: -------------------------------------------------------------------------------- 1 | ### 1.7.2 基于服务的云原生应用体系结构 2 | 3 | 在本书中,您将依据 `基于服务` 的体系结构来设计开发云原生应用。 4 | 5 | 您的主要工作内容,是开发一个可以用不同方式与其他服务交互的服务。利用 Cornelia Davis 提出的区别,我们可以确定这种架构中的两个重要元素:服务和交互。 6 | * **服务(Service)**:向另一个组件提供服务的组件。 7 | * **交互(Interaction)**:完成系统要求的,服务之间的通信。 8 | 9 | 服务是非常通用的组件,它们可能是任何东西。我们可以对它们进行分类,考虑它们是否存储任何类型的状态,可区分应用程序服务(无状态)和数据服务(有状态)。图 1.14 显示了这种云原生体系结构的要素。 10 | 11 | ![](../../assets/1.14.jpg) 12 | **图 1.14 云原生应用程序的基于服务的体系结构。主要元素是服务(应用程序或数据)以不同方式相互作用。** 13 | 14 | #### 应用程序服务 15 | 16 | 应用程序服务是无状态的,负责实现任何类型的逻辑。他们不必遵守微服务相关的规则,只要它们暴露出云原生应用的属性就行。 17 | 18 | 最重要的是,在设计每个服务时都要考虑到松耦合和高内聚。服务应尽可能独立。分布式系统是复杂的,所以您应该在设计阶段格外小心。服务数量的增加将导致问题数量的增加。 19 | 20 | 您可能会独自开发和维护系统中的大多数应用程序服务,但您也可以使用云服务商提供的一些服务,如身份验证或支付服务。 21 | 22 | #### 数据服务 23 | 24 | 数据服务是有状态的,负责存储任何类型的状态。`状态(state)` 就是一切应该保留的信息,比如在关闭服务并启动新实例时。 25 | 26 | 它们可以是关系数据库(如 PostgreSQL)、键/值存储(如 Redis)或消息代理(如 RabbitMQ)。您可以自己管理这些服务。因为云原生应用要使用存储来保存状态,这会比您的想象要更具挑战,当然您也会因此而将获得更多控制自己数据的便利。另一种选择是使用云服务商的数据服务,服务商将负责管理与存储、恢复、扩展和性能。在这种情况下,还可以利用专门为云端处理大量数据而构建的服务(如 Amazon DynamoDB 或 Google BigQuery)。 27 | 28 | 云原生数据服务是一个迷人的主题,但在本书中,我们将主要讨论应用程序。与数据相关的问题,如集群、复制、一致性或分布式事务不会在书中详述。我很想介绍这些,但它们值得用专门的一本书去介绍。 29 | 30 | #### 交互 31 | 32 | 云原生服务相互通信以满足系统的需求。通信方式将影响系统的整体特性。例如:选择 `请求/响应` 模式(同步 HTTP 调用)而不是基于事件的方法(通过 RabbitMQ 传输的消息)将导致不同级别的恢复能力。在本书中,您将使用各种不同类型的通讯方式,会了解不同通讯方式之间的差异,以及掌握在何时选择何种方式。 33 | -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 1.7 云原生应用架构 2 | 3 | 我们已经到了定义云原并介绍在本书中所依赖的主要技术的最后一步。在上一节中,您已经熟悉了云原生拓扑,特别是容器,将成为我们的计算单元。现在,让我们看看里面有什么,并探索云原生应用有关的架构和设计的高级原则。图 1.12 显示了本节涵盖的主要概念。 4 | 5 | ![](../../assets/1.12.jpg) 6 | **图 1.12 云原生架构元素。** -------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/Introduction.md: -------------------------------------------------------------------------------- 1 | # 第 1 章 云原生简介 2 | 3 | 本章内容: 4 | 5 | * 什么是云和云计算模型 6 | * 云原生的定义 7 | * 云原生应用的特性 8 | * 支持云原生的文化和实践 9 | * 您应该考虑云原生的时间点和原因 10 | * 云原生应用程序的拓扑和体系结构 11 | 12 | 云原生应用是高度分布式的系统,它们运行在云中,对变化的适应能力很强。系统由多个服务组成,这些服务通过网络进行通信,并部署在动态环境中,其中所有内容都在不断变化。 13 | 14 | 在深入研究 Spring、Docker 和 Kubernetes 之前,最基本的是首先定义什么是云原生。像我们领域中的其他流行语(如敏捷、DevOps 或 微服务)一样,云原生有时会被误解,并且可能会引起混淆,因为它对不同的人意味着不同的事情。 15 | 16 | 在本章中,我将为您提供本书其余部分所需的概念。首先,我将定义云原生并说明一个应用成为云原生应用所需的条件。我将解释云原生应用程序的属性,考查云计算模型的特性,并讨论您应该何时以及为什么要迁移到云。我还将介绍一些云原生拓扑和体系结构的基本概念。图 1.1 显示了我将在本章中介绍的所有不同元素的概述,以定义和限定云原生系统。在本章的最后,您将开始使用 Spring 构建云原生应用程序并使用 Kubernetes 部署它们的旅程。 17 | 18 | 19 | ![](../assets/1.1.jpg) 20 | **图 1.1 云原生是一种利用云技术的应用程序开发方法。本章涵盖六个主要领域来定义什么是云原生:云计算、应用程序属性、实践、拓扑、体系结构和目标。**
-------------------------------------------------------------------------------- /cn-translate/01-Introduction-to-cloud-native/Summary.md: -------------------------------------------------------------------------------- 1 | ## 1.8 总结 2 | 3 | * 云是一种 IT 基础设施,以商品的形式提供计算、存储和网络资源。用户只为实际使用的资源付费。 4 | * 云原生应用程序是专为云端运行的应用而设计的高度分布式系统。 5 | * 云服务商以不同的抽象级别提供服务:基础设施即服务(IaaS)、容器即服务(CaaS)、平台即服务(PaaS)、功能即服务(FaaS)或软件即服务(SaaS)。 6 | * 云原生应用程序具有水平可扩展性、松散耦合性和高度内聚性,具有故障恢复能力、可管理性和可观察性。 7 | * 云原生开发由自动化、持续交付和 DevOps 支持。云原生是一种文化,支持不同角色之间的协作,以共同交付业务价值。 8 | * 现代企业采用云原生技术开发快速交付的软件,可根据需求动态缩放,且始终可用,在优化成本的同时具有故障恢复能力。 9 | * 容器可以用作计算单元来设计云原生系统。他们比虚拟机更轻量,并提供可移植性、不变性和灵活性。如:Docker。 10 | * 专用平台提供管理容器的服务,而无需直接处理底层。它们提供容器编排、集群管理、网络服务和调度。如:Kubernetes。 11 | * 无服务器模式是一种云服务商管理服务器和后端函数的模式,而开发人员只需关注业务逻辑。后端函数在每次使用时计费,以实现成本优化。如:Google Functions。 12 | * 微服务架构可以用于开发云原生应用程序,但并不是必须的。云原生与微服务不完全相同。 13 | * 要设计云原生应用程序,您可以使用 `基于服务` 的架构,其要素是:服务和交互。服务可以进一步分为:应用程序服务(无状态)和数据服务(有状态)。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.1-One-codebase-one-application.md: -------------------------------------------------------------------------------- 1 | ### 2.1.1 一份基准代码对应一个应用 2 | 3 | 该方法论建立了应用程序及其代码库之间的一对一映射。所以一个应用程序一个代码库。任何共享的代码都应该作为一个整体,在其自己的代码库中进行跟踪。应作为可独立运行的依赖库或其他服务包含的库,或作为其他应用程序的支持服务。每个基准代码都保存在其自己的存储库中。 4 | 5 | 每一个部署就是应用程序的一个运行实例。多个部署可能以不同的方式部署在不同的环境,但都共享相同的基准代码。在特定环境部署应用程序,无需重新构建基准代码库:在部署之间进行的任何更改(例如,配置)要在应用程序基准库之外。 6 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.10-Administrative-processes.md: -------------------------------------------------------------------------------- 1 | ### 2.1.10 管理员进程 2 | 3 | 通常需要一些管理任务来支持应用程序。像数据库迁移、批处理作业或维护作业这样的任务应视为一次性的。管理任务也一样应这样考虑,这表示应在版本控制中跟踪管理任务的代码,和它们支持的应用程序一起交付,并与应用在同一环境中执行。 4 | 5 | 通常,将管理任务框架化为小型独立服务是一个好主意,这些服务只运行一次,然后就被扔掉。在无状态平台中配置功能,在某些事件发生时触发,或嵌入到应用程序中,通过调用特定接口来激活它们。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.11-Port-binding.md: -------------------------------------------------------------------------------- 1 | ### 2.1.11 端口绑定 2 | 3 | 采用 `十五要素` 方法论的应用程序应是自给的,并通过端口绑定对外提供服务。在生产中,可能会有一些路由服务,将公共端点请求转到内部端口绑定的服务上。 4 | 5 | 如果一个应用程序不依赖于执行环境中的外部服务器,则该应用程序是自给的。Java web 应用程序可能会在应用服务器中运行,如 6 | Tomcat 或 Undertow。云原生应用程序不需要环境中有 Tomcat 服务器,但它会像任何其他依赖项一样管理它自己。如 Spring Boot 7 | 允许您使用嵌入式服务器:应用程序将包含服务器,而不是取决于执行环境中是否有可用的服务器。其后果之一是,应用程序和服务器之间始终存在一对一的映射,这与将多个应用程序部署到同一服务器的传统方法不同。 8 | 9 | 应用程序提供的服务通过端口绑定暴露。web 应用程序将 HTTP 服务绑定到特定端口,并可能成为其他应用程序的后端服务。这是在云原生系统中经常发生的情况。 10 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.12-Stateless-processes.md: -------------------------------------------------------------------------------- 1 | ### 2.1.12 无状态进程 2 | 3 | 在上一章中,您看到了高伸缩性是我们转向云的原因之一。为了确保可扩展性,我们将应用程序设计为无状态进程,并采用 `无共享架构(share-nothing architecture)`:不同的应用程序实例之间不应共享任何状态。问问自己,如果数据都丢失了,应用程序的实例是否应被销毁并重新创建。如果答案是肯定的,那么您的应用程序不是无状态的。 4 | 5 | 不管怎样,我们总是需要保存一些状态,否则大多数情况下我们的应用程序在都没什么用。因此,我们将应用程序设计为无状态,然后限制要在有状态服务中处理,如数据存储。换句话说,无状态应用程序委托后端服务进行状态管理和存储。 6 | 7 | 8 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.13-Concurrency.md: -------------------------------------------------------------------------------- 1 | ### 2.1.13 并发 2 | 3 | 无状态应用不足以实现可伸缩性。如果需要扩展,这意味着您需要为更多用户服务。因此,您的应用程序应该允许并发,以同时为大量用户提供服务。 4 | 5 | 该方法论将进程定义为 `一等公民`。这些进程应该是水平可伸缩的,将工作负载分布在不同机器上的多个进程上。只有当应用程序是无状态的,才可能进行这种并发处理。在 JVM 应用程序中,我们通过线程池中的多个线程来处理并发性。 6 | 7 | 进程可以根据其类型进行分类。例如,您可能有 web 进程处理 HTTP 请求和在后台执行计划作业的工作进程。 8 | 9 | 10 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.14-Telemetry.md: -------------------------------------------------------------------------------- 1 | # 2.1.14 遥测 2 | 3 | 可观察性是云原生应用程序的特性之一。在云端管理分布式系统是复杂的。管理这种复杂性的唯一机会是,确保每个系统组件都提供正确的数据,来远程监视系统的行为。遥测数据包括日志、度量、跟踪、运行状况和事件。`Hoffman` 使用一个非常吸引人的图像来强调监督的重要性:像对待空间探测器一样对待您的应用程序。您需要什么样的遥测技术来远程监视和控制您的应用程序呢? -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.15-Authentication-and-authorization.md: -------------------------------------------------------------------------------- 1 | # 2.1.15 认证和授权 2 | 3 | 安全性是软件系统的基础品质之一,但它往往得不到应有的重视。毫无疑问,安全不仅仅是身份验证和授权,但这是一个很好的起点。 4 | 5 | 通过身份验证,您可以跟踪使用该应用程序的人。知道了这一点,您可以检查用户权限,以验证是否允许他们执行特定的操作。有一些标准可用于实现身份和访问管理,包括我们将在本书中使用 OAuth 2.0 和 OpenID Connect。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.2-API-first.md: -------------------------------------------------------------------------------- 1 | ### 2.1.2 API 优先 2 | 3 | 云原生系统通常由通过 API 进行通信的不同服务组成。在设计云原生应用程序时,使用 `API 优先` 的方法鼓励将其安装到分布式系统中,并支持在不同的团队之间协同工作。通过先设计 API,另一个团队可以将该应用程序用作支持服务。根据该 API 创建他们的解决方案。通过提前约定的这个 `合同`,与其他系统的集成将更加健壮和并易于测试。内部 API 的实现可以在不影响其他应用程序(和团队)的情况下进行更改。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.3-Dependency-management.md: -------------------------------------------------------------------------------- 1 | ### 2.1.3 依赖管理 2 | 3 | 所有应用程序依赖项都应在清单中显式声明,并可用依赖项管理器从中央存储库下载。考虑 Java 应用程序,我们通常能够很好地使用Maven 或 Gradle 来遵循这一原则。应用程序对周围环境的唯一隐式依赖关系是,相关语言的运行库和依赖项管理器工具。 4 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.4-Design-build-release-run.md: -------------------------------------------------------------------------------- 1 | ### 2.1.4 设计、构建、发布、运行 2 | 3 | 代码库在从设计到生产部署的过程中经历了不同的阶段。 4 | * 设计阶段。确定特定应用程序特性所需的技术、依赖和工具。 5 | * 构建阶段。构建是指代码库连同其依赖项一起编译和打包为不可变工件。工件必须是具有唯一标识的。 6 | * 发布阶段。构建与特定配置相结合进行部署。每个发布是不可变的,并且应该是唯一可识别的,例如,使用版本(如 3.9.4)或时间戳(如 2015-10-21-07:28)。发布产品应存储在中央存储库中以便于访问,比如回滚到上一个版本就需要用到存储库。 7 | * 运行阶段。应用程序在执行环境中运行特定发布版本。 8 | 9 | 该方法论要求严格分离这些阶段,不允许更改运行时代码,因为这会导致与构建阶段不匹配。构建与发布的工件应该是不可变的,并用唯一标识符标记,以保证再现性。 10 | 11 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.5-Configuration-credentials-and-code.md: -------------------------------------------------------------------------------- 1 | ### 2.1.5 配置、证书、代码 2 | 3 | `15 因素` 法将配置定义为,在不同部署之间可能发生变化的一切东西。每当您需要更改应用程序的配置时,您应该能够不需要对代码进行任何更改,也不需要再次构建应用程序。 4 | 5 | 配置可能包括支持服务的资源,如数据库或消息系统、访问第三方 API 的凭据和特性标志位。问问您自己,如果您的代码库变成公开的,是否有凭据或特定于环境的信息将被泄露。这将告诉您是否正确地使用了配置。 6 | 7 | 为了符合这个要素,您不能在代码中有配置,也不能在基准代码中包含配置。您可以使用配置文件,但应将其存储在单独的数据存储库中。该方法建议将配置存储为环境变量。这样,您就可以在不同的环境中部署相同的应用程序,不同的行为只取决于环境的配置。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.6-Logs.md: -------------------------------------------------------------------------------- 1 | ### 2.1.6 日志 2 | 3 | 云原生应用程序不关心日志的路由和存储。申请应记录到标准输出,将日志视为按时间顺序发出的事件。日志存储和轮换不再是应用程序的职责。像 Fluent Bit 这样的外部工具将获取、收集并提供日志检查。 4 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.7-Disposability.md: -------------------------------------------------------------------------------- 1 | ### 2.1.7 可丢弃 2 | 3 | 在传统环境中,您需要非常小心地对待您的应用程序,确保它们保持持续运行,永不终止。在云环境中,您不用太在意:应用实例的存活是短暂的。如果发生故障,应用程序不再响应,您可以终止它并启动一个新实例。如果您有一个高负载峰值,您以更快的速度增加新实例,以支持更高的工作负载。我们说应用程序实例是可以随时启动或停止的,则为`可丢弃`。 4 | 5 | 要以这种动态方式处理应用程序实例,您应该将它们设计为,在需要新实例时可快速启动,在不需要时优雅地关闭。快速启动可实现系统的弹性,确保鲁棒性和韧性。没有快速启动,您将面临性能和可用性问题。 6 | 7 | 当应用程序收到终止信号时,即正常关闭:它停止接受新的请求,完成正在处理的请求,最后退出。对于 web 进程,这很简单。在其他情况下,例如在工作进程中,它们必须将负责的任务退回工作队列,然后才能退出。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.8-Backing-services.md: -------------------------------------------------------------------------------- 1 | ### 2.1.8 后端服务 2 | 3 | 支持服务可以定义为应用程序用于交付其功能的外部资源。支持服务的示例包括数据库、消息代理、缓存系统、SMTP 服务器、FTP 服务器或 RESTful web 服务。将其视为附加资源意味着您可以轻松地更改它们,而无需修改应用程序代码。 4 | 5 | 考虑在整个软件开发生命周期中是如何使用数据库的。一定是根据开发、测试或生产环境的不同使用不同的数据库。如果将数据库视为附加的资源,则可以根据不同的环境使用不同的后端服务,这是通过资源绑定完成的。比如,数据库资源绑定由 URL、用户名和数据库密码组成。 6 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.9-Environment-parity.md: -------------------------------------------------------------------------------- 1 | ### 2.1.9 环境一致性 2 | 3 | 环境一致性是指要使所有环境尽可能相似。事实上,完全有可能找出该因素所指的这些差别: 4 | * **时间间隙**。代码更改和部署之间的时间间隙可能相当长。这个该方法致力于促进自动化和连续部署,减少从开发人员编写代码到部署到生产的时间差。 5 | * **人与人之间的间隔**。开发人员构建应用程序,而运维人员管理生产环境中的部署。这个差别可以通过拥抱 DevOps 文化,拥有更好的开发和运维协作,实现“您构建它,您运行它”的“哲学”。 6 | * **工具差异**。环境之间的主要区别之一是后端服务差异。例如,开发人员可能在其本地数据库中使用 H2 数据库,而在生产中使用 PostgreSQL。一般来说,在所有环境中都应使用相同类型和相同版本的后端服务。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 2.1 云原生开发原则:十二要素及其他 2 | 3 | Heroku 云平台的工程师们提出了 `十二要素`,作为设计和构建云原生应用的开发原则。他们将经验提炼为构建 web 应用程序的最佳实践,具有以下特点: 4 | 5 | * 适合部署在云平台上; 6 | * 可扩展的设计; 7 | * 可跨系统移植; 8 | * 可实现连续部署和灵活性。 9 | 10 | 目标是帮助开发人员为云构建应用程序,突出最重要的因素才能达到最好的效果。 11 | 12 | 后来,Kevin Hoffman 在《Beyond the Twelve-Factor App》一书中对该方法进行了修订和扩展,更新了原来的要素内容,并添加了三个额外要素。现在,我将把这套原则称为 `十五要素` 方法。 13 | 14 | 总的来说,这 15 个要素将本书整个过程中时刻给您指导,因为它们是开发云原生应用的一个良好的开端。如果您是从头开始构建新的应用程序,或者将传统系统迁移到云上,这些原则可以帮助您实现这一过程。我将在相关部分详细介绍它们,并说明如何将它们应用于 Spring 15 | 应用程序。但重要的是先要熟悉它们。 16 | 17 | 让我们逐一深入研究。 18 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/2.2.1-Overview-of-the-Spring-landscape.md: -------------------------------------------------------------------------------- 1 | ### 2.2.1 Spring 全景概览 2 | 3 | Spring 包含几个项目,以解决软件开发的许多不同需求:web 应用程序、安全性、数据访问、集成、批处理、配置、消息传递、大数据等等。Spring 平台的美妙之处在于它的设计是模块化的,因此,您可以只使用和组合需要的项目。不管您要构建何种类型的应用程序,Spring 基本上都能帮到您。 4 | 5 | Spring 框架是 Spring 平台的核心,是一切项目的起点。它支持依赖注入、事务管理、数据访问、消息传递、web 应用程序等。该框架建立了企业应用程序的“管道”,让您能够专注于业务逻辑。 6 | 7 | Spring 框架提供了一个执行上下文(称为 `Spring context` 或 `container`),其中 bean、属性和资源在整个应用程序生命周期中都得到管理。我假设您已经熟悉该框架的核心功能,所以我不会在这里花费太多时间。特别是,您应该意识到 Spring 上下文的作用,并熟练使用 Spring bean、基于注解的配置和依赖注入。我们将依靠这些特性,所以您应该把它们搞明白。 8 | 9 | 基于该框架,Spring Boot 使快速构建独立的和生产就绪的应用成为可能。通过对 Spring 和第三方库的固定约束,Spring Boot 附带了一个合理的默认配置,让开发人员通过最少的前期工作,直接使用它。 10 | 11 | 在本书中,您将有机会使用几个 Spring 项目,来实现各种不同模式及进行开发云原生应用的最佳实践,包括 Spring Boot、Spring cloud、Spring Data 、Spring Security、Spring Session 和 Spring Native。 12 | 13 | 如果您有兴趣了解更多关于 Spring 核心特性的相关信息,Manning 有几本相关书籍:Laurențiu Spilcă 的《Spring Start Here》([http://www.manning.com/books/spring-quickly](http://www.manning.com/books/spring-quickly))和 Craig Walls 的《Spring in Action》([https://www.manning.com/books/spring-in-action-sixth-edition](https://www.manning.com/books/spring-in-action-sixth-edition))。 14 | 15 | >译者注:《Spring 实战》第 6 版 MEAP 已翻译完成,地址:[https://github.com/LeonLi0102/spring-in-action-v6-translate](https://github.com/LeonLi0102/spring-in-action-v6-translate) 16 | 17 | 18 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/2.2.2-Building-a-Spring-Boot-application.md: -------------------------------------------------------------------------------- 1 | ### 2.2.2 创建 Spring Boot 应用 2 | 3 | 假设您为 Polarsophia 构建一个 `极地书店` 应用程序。该组织管理着一家特殊的书店,希望出售有关北极的书籍。正在考虑采用云原生方法。 4 | 5 | 作为一个试点项目,您的老板指派您向同事演示,如何在云中开发及部署。要求您构建的 web 应用程序是一个 `目录服务(Catalog Service)`,目前只有一个职责:欢迎用户访问图书目录。 6 | 7 | 这个试点项目,将为构建出成功并受到好评的云原生应用打下基础。 8 | 9 | 考虑到任务的目标,您可能会决定将应用程序实现为 RESTful 服务,使用一个 HTTP 端点负责返回欢迎消息。毫无疑问的是,您选择采用 Spring 作为服务(目录服务)的主要技术栈。系统的体系结构如图 2.2 所示。在接下来的部分,您将尝试构建和部署应用程序。 10 | 11 | ![](../../assets/2.2.jpg) 12 | **图 2.2 遵循 C4 模型的 `极地书店` 应用程序的体系结构图。**
13 | 14 | 在图 2.2 中,您可以看到一些体系结构符号,这些符号将会贯穿本书。这些符号遵循 [Simon Brown](https://simonbrown.je/) 创建的 [C4](https://c4model.com/) 模型。为描述 `极地书店` 项目,模型中有三个抽象: 15 | * **人**。代表软件系统的一个人类用户。在我们的示例中,它是书店的顾客。 16 | * **系统**。它代表您为向用户提供价值而构建的整体应用程序。在这里表示,`极地书店` 系统。 17 | * **容器**。它表示应用程序或数据的服务。不要与 Docker 混淆了。在我们的示例中,它是 Catalog Service。 18 | >译者注:C4表示上下文(Context)、容器(Container)、组件(Component)和代码(Code) 19 | 20 | 对于此任务,您可以使用 Spring 框架和 Spring Boot 执行以下操作: 21 | * 声明实现应用程序所需的依赖项; 22 | * 使用 Spring Boot 引导应用程序; 23 | * 实现控制器以公开用于返回欢迎消息的 HTTP 端点; 24 | * 运行并使用应用程序。 25 | 26 | 本书中的所有示例都基于 Java 17,因此您需要安装 OpenJDK 17。我将使用来自 Adoptium 项目([adoptium.net](https://adoptium.net/))的 Eclipse Temurin,以前称为 AdoptOpenJDK。您可以选择其他合适的版本。 27 | 28 | >注意:在您的计算机上管理不同的 Java 发行版可能会很困难。我建议使用 SDKMAN([sdkman.io](https://sdkman.io/))这样的工具轻松安装、更新,并在不同的 JDK 之间进行切换。 29 | 30 | #### 初始化项目 31 | 32 | 在本书中,我们将构建几个云原生应用程序。我建议您为每个应用建立一个 Git 存储库,并在 GitHub 进行存储。在下一章中,我将更多地讨论如何管理代码库的内容。现在,请创建一个 catalog-service 的 Git 存储库。 33 | 34 | 然后,您可以使用 Spring Initializr ([start.Spring.io](https://start.spring.io/))生成项目,并将其存储在刚刚创建的 catalog-service Git 存储库中。Spring Initializr 是一个方便使用的服务,可以从浏览器或通过其 REST API 进行访问,以生成基于 JVM 的工程。它甚至集成进了流行的 IDE 中,如 IntelliJ IDEA、Visual Studio Code 和 Eclipse。初始化 Catalog Service 的参数如图 2.3 所示。 35 | 36 | ![](../../assets/2.3.jpg) 37 | **图 2.3 从Spring Initializr 初始化 Catalog Service 项目的参数。**
38 | 39 | 在初始化过程中,您可以提供有关要构建的应用程序的一些详细信息,如表 2.1 所示。 40 | 41 | **表 2.1 使用 Spring Initializr 生成项目时,可配置的主要参数。** 42 | 43 | | 参数 | 描述 | Catalog Service 服务所用值 | 44 | | :--- | :--- | :--- | 45 | | Project | 您可以使用 Gradle 或 Maven 作为项目的构建工具。这本书中所有的例子都将使用 Gradle。 | Gradle | 46 | | Language | Spring 支持三种主要的 JVM 语言:Java、Kotlin、Groovy。本书中的所有示例都将使用 Java。 | Java | 47 | | Spring Boot | 您可以选择要安装的 Spring Boot 版本。本书中的所有示例都将使用 Spring Boot 2.6.0-RC1,但任何 2.6+ 版本都应可以。 | Spring Boot 2.6.0-RC1 | 48 | | Group | 项目的组 ID,在 Maven 存储库中使用。 | com.polarbookshop.catalogservice | 49 | | Artifact | 项目的工件 ID,在 Maven 存储库中使用。 | catalog-service | 50 | | Name | 工程名称。 | catalog-service | 51 | | Package name | 项目的基本 Java 包。 | com.polarbookshop.catalogservice | 52 | | Packaging | 如何打包项目:WAR(用于在应用服务器上部署)或 JAR(用于独立应用程序)。云原生应用程序应该打包为 JAR,所以 53 | 本书中的示例将使用该选项。 | JAR | 54 | | Java | 要用于构建项目的 Java 版本。本书中的所有示例都将使用 Java 17。 | 17 | 55 | | Dependencies | 要包含在项目中的依赖项。 | Spring Web | 56 | 57 | 新生成项目的结构如图 2.4 所示。在接下来的部分,我带领您一步步操作。 58 | 59 | ![](../../assets/2.4.jpg) 60 | 61 | **图 2.4 从Spring Initializr 生成的新 Spring Boot 项目的结构。**
62 | 63 | 在本书附带的代码存储库中([github.com/ThomasVitale/cloud-native-spring-In-action](https://github.com/ThomasVitale/cloud-native-spring-in-action)),对于每一章都可以找到 begin 和 end 文件夹。您都可以从与我相同的设置开始,并检查最终结果。例如,您当前正在阅读第 2 章,因此您将在 Chapter02/02-begin 和 Chapter02/02-end 中找到相关代码。 64 | 65 | >注意:在本章的 begin 文件夹中,您可以找到在终端窗口中运行的命令,该窗口下载一个 zip 文件,其中包含您需要下载的所有代码。而无需通过 Spring Initializr 手动生成。 66 | 67 | >Gradle 或 Maven?? 68 | > 69 | >在本书中,我使用的是 Gradle,但您也可以使用 Maven。在本书附带的代码存储库中,您可以找到一个 Gradle 命令映射表,以便在使用 Maven 时使用([github.com/ThomasVitale/cloudnativespring-in-action](https://github.com/ThomasVitale/cloud-native-spring-in-action))。每个项目有不同的需求,这可能导致您选择某个构建工具。 70 | > 71 | >我选择使用 Gradle 主要有两个原因。使用 Gradle 构建和测试 Java 项目比使用 Maven 要花费更少的时间,这得益于其增量和并行构建以及缓存。此外,我发现 Gradle 构建语言(Gradle DSL)更具可读性,也比 Maven XML 更具表现力和可维护性。在 Spring 的生态系统中,您既可以找到使用 Gradle 的项目,也可以找到使用 Maven 的项目。它们都有各自的拥挤者。我建议您可以都尝试一下,然后再选择让您的生产率更高的那个。 72 | 73 | #### 探索构建配置 74 | 75 | 让我们首先打开您刚刚初始化的项目,并查看 Gradle 构建出来的 Catalog Service 应用程序的配置,这是在 build.gradle 文件中定义的。您可以在那里找到您提供给 Spring Initializr 的所有信息。 76 | 77 | **清单 2.1 Catalog Service 项目的构建配置(build.gradle)** 78 | 79 | ```text 80 | plugins { 81 | id 'org.springframework.boot' version '2.6.0-RC1' ❶ 82 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' ❷ 83 | id 'java' ❸ 84 | } 85 | 86 | group = 'com.polarbookshop' ❹ 87 | version = '0.0.1-SNAPSHOT' ❺ 88 | sourceCompatibility = '17' ❻ 89 | 90 | repositories { ❼ 91 | mavenCentral() 92 | maven { url 'https://repo.spring.io/milestone' } 93 | } 94 | 95 | dependencies { 96 | implementation 'org.springframework.boot:spring-boot-starter-web' ❽ 97 | testImplementation 'org.springframework.boot:spring-boot-starter-test' ❾ 98 | } 99 | 100 | test { 101 | useJUnitPlatform() ❿ 102 | } 103 | ``` 104 | 105 | ❶ 在 Gradle 中提供 Spring Boot 支持,并声明您想要的版本 106 | ❷ 为 Spring 提供依赖项管理功能。 107 | ❸ 在 Gradle 中提供 Java 支持,设置任务以编译、构建和测试应用 108 | ❹ Catalog Service 项目的组 ID。 109 | ❺ 应用程序的版本。默认情况下为 0.0.1-SNAPSHOT。 110 | ❻ 用于构建项目的 Java 版本。 111 | ❼ 工件存储库,指定搜索依赖项的位置。 112 | ❽ 提供使用 Spring MVC 构建 web 应用程序所需的库,引入 Tomcat 作为默认的嵌入式服务器。 113 | ❾ 提供多个库和实用程序来测试应用程序,包括 Spring Test、JUnit 和 Mockito。自动包含在每个 Spring Boot 项目中。 114 | ❿ 支持使用 JUnit5 提供的 JUnit 平台进行测试。 115 | 116 | 项目名称在名为 settings.gradle 的第二个文件中定义。 117 | 118 | ```text 119 | rootProject.name = 'catalog-service' 120 | ``` 121 | 122 | Spring Boot 提供了方便的 starter 依赖项,特定用例所必需的库都捆绑在了一起,此功能显著简化了构建配置。这个项目使用的主要依赖项是 `org.springframework.boot:spring-boot-starter-web`,在 Spring Initializr 中名为 `Spring Web`。此 starter 用于构建 web 应用程序,包括构建具有 RESTful 服务的功能,并引入 Apache Tomcat 作为默认的嵌入式服务器。 123 | 124 | #### 引导应用程序 125 | 126 | 在上一节中,您初始化了 Catalog Service 项目并选择了 JAR 打包选项。任何打包为 JAR 的 Java 应用程序都必须具有 `public static void main(String[] args)` 方法,以在启动时执行。Spring Boot 也不例外。在 Catalog Service 里,您有了一个 CatalogServiceApplication 类,该类是在初始化时自动生成的:类中定义了 `main()` 方法,也是 Spring Boot 应用程序的入口点。 127 | 128 | **清单 2.2 Catalog Service 的引导类(CatalogServiceApplication.java)** 129 | 130 | ```java 131 | package com.polarbookshop.catalogservice; 132 | 133 | import org.springframework.boot.SpringApplication; 134 | import org.springframework.boot.autoconfigure.SpringBootApplication; 135 | 136 | @SpringBootApplication ❶ 137 | public class CatalogServiceApplication { 138 | 139 | public static void main(String[] args) { ❷ 140 | SpringApplication.run(CatalogServiceApplication.class, args); ❸ 141 | } 142 | 143 | } 144 | ``` 145 | 146 | ❶ 定义 Spring 配置类,触发组件扫描和 Spring Boot 自动配置。 147 | ❷ 用于启动应用程序的方法。 148 | ❸ 注册要在应用程序引导阶段运行的当前类。 149 | 150 | `@SpringBootApplication` 注解是包含三种不同注解的快捷方式: 151 | * `@Configuration` 将该类标记为 bean 定义源。 152 | * `@ComponentScan` 启动组件扫描,能够在 Spring 上下文中自动查找和注册 bean。 153 | * `@EnableAutoConfiguration` 启用由 Spring Boot 提供的自动配置功能。 154 | 155 | Spring Boot 自动配置会根据多种情况被触发,例如:类路径中是否存在某些类、特定 bean 的存在或某些类的属性值。由于 Catalog Service 项目依赖于 spring-boot-starter-web,所以 Spring Boot 将初始化嵌入式 Tomcat 服务器实例并应用最小配置,在几乎零时间内启动并运行 web 应用程序。 156 | 157 | 应用程序的设置就是这样。让我们继续为 Catalog Service 开发 HTTP 端点。 158 | 159 | #### 实现控制器 160 | 161 | 到目前为止,我们已经了解了由 Spring Initializr 生成的项目。是时候开发一些应用程序的业务逻辑了。Catalog Service 将公开 HTTP 端点并返回欢迎信息。这可以在 REST 控制器中为其定义一个处理程序。它将是一个 GET 端点,向用户返回一条欢迎消息,欢迎用户访问图书目录。图 2.5 显示了交互流程。 162 | 163 | ![](../../assets/2.5.jpg) 164 | **图 2.5 用户和应用程序之间的交互,由 Catalog Service 公开的 HTTP 端点返回欢迎消息。** 165 | 166 | 在 Catalog Service 项目中,创建一个新的 HomeController 类并实现一个方法,负责处理对根路径(`/`)的 GET 请求。 167 | 168 | **清单 2.3 定义一个 GET 端点以返回欢迎消息(HomeController.java)** 169 | ```java 170 | package com.polarbookshop.catalogservice; 171 | 172 | import org.springframework.web.bind.annotation.GetMapping; 173 | import org.springframework.web.bind.annotation.RestController; 174 | 175 | @RestController ❶ 176 | public class HomeController { 177 | 178 | @GetMapping("/") ❷ 179 | public String getGreeting() { 180 | return "Welcome to the book catalog!"; 181 | } 182 | 183 | } 184 | 185 | ``` 186 | 187 | ❶ 定义处理程序的类,标识为 REST 端点。 188 | ❷ 处理对根路径的 GET 请求。 189 | 190 | `@RestController` 注解将类标识为处理传入的 HTTP 请求。使用 `@GetMapping` 注解,可以将 `getGreeting()` 方法标记为:到达根路径 (`/`) GET 请求的处理程序。对该端点的任何 GET 请求都将用这个方法进行处理。在下一章中,我将更详细介绍如何使用 Spring。 191 | 192 | #### 测试应用程序 193 | 194 | 从 Spring Initializr 创建 Spring 项目时,包含基本的测试设置。在 build.gradle 文件中,自动添加了测试 Spring 所需的依赖项。此外,还自动生成一个测试类。让我们来看看自动生成的 CatalogServiceApplicationTests 类是什么样的。 195 | 196 | **清单 2.4 验证 Spring 上下文的自动生成的测试类(CatalogServiceApplicationTests.class)** 197 | 198 | ```java 199 | package com.polarbookshop.catalogservice; 200 | 201 | import org.junit.jupiter.api.Test; 202 | import org.springframework.boot.test.context.SpringBootTest; 203 | 204 | @SpringBootTest ❶ 205 | class CatalogServiceApplicationTests { 206 | 207 | @Test ❷ 208 | void contextLoads() { ❸ 209 | } 210 | 211 | } 212 | ``` 213 | 214 | ❶ 提供用于测试 Spring Boot 应用程序的设置。 215 | ❷ 标识一个测试用例。 216 | ❸ 用于验证应用程序上下文是否正确加载的空测试。 217 | 218 | 默认测试类由 `@SpringBootTest 注解标识,该注解提供了许多测试 Spring Boot 应用程序的有用功能。在整本书中,我会更多介绍它们。现在,只需知道它加载了一个完整的 Spring 应用程序上下文就可以了。这里只有一个测试用例,而且是空的:它用于验证 Spring 上下文是否已正确加载。 219 | 220 | 打开终端窗口,导航到应用程序根文件夹(catalog-service),然后运行 Gradle 任务 test,来执行应用程序测试。 221 | 222 | ```bash 223 | $ ./gradlew test 224 | ``` 225 | 226 | 任务应该是成功的,测试是绿色的,这意味着 Spring 应用程序可以启动,没有错误。但 HTTP 端点呢?让我们来看一看。 227 | 228 | #### 运行应用程序 229 | 230 | 您已经完成了应用程序的创建,因此可以运行它了。有很多不同的方法可以运行应用程序,稍后我将向您展示其中的一些方法。现在,您可以使用 Spring Boot Gradle 插件提供的 bootRun。 231 | 232 | 在启动测试的同一终端窗口中,运行以下命令: 233 | 234 | ```bash 235 | $ ./gradlew bootRun 236 | ``` 237 | 238 | 几秒钟后,应用程序应该启动并开始运行,并准备好接受请求。在图 2.6 中,您可以看到启动阶段的日志。 239 | 240 | ![](../../assets/2.6.jpg) 241 | **图 2.6 Catalog Service 应用程序的启动日志。** 242 | 243 | 图 2.6 中的日志中,您可能注意到启动阶段由两个主要步骤组成: 244 | * 初始化和运行嵌入式 Tomcat 服务器(默认情况下,侦听端口 8080); 245 | * Spring 应用程序上下文的初始化和运行。 246 | 247 | 现在,您可以验证 HTTP 端点是否按预期工作了。打开浏览器窗口,访问 localhost:8080/ 并准备好接收本书的欢迎目录吧。 248 | 249 | ```text 250 | Welcome to the book catalog! 251 | ``` 252 | 253 | `极地书店` 应用程序的开发部分已经完成:您有了一个 Catalog Service 欢迎用户使用图书目录。记住终止 bootRun 进程可以使用 `Ctrl+C` 以停止应用程序的执行。 254 | 255 | 下一步是将应用程序部署到云中。要使其在任何云基础设施上都可运行,您应该首先将其容器化。下面我们讲 Docker。 256 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 2.2 使用 Spring 构建云原生应用 2 | 3 | 是时候开始具体谈一些技术了。到目前为止,您已经熟悉了云原生方法和要遵循的主要开发实践。现在,让我们看看 Spring。您正在读这本书,您应该有一些使用 Spring 的经验,希望了解如何使用它构建云原生应用程序。 4 | 5 | Spring 生态系统提供的特性几乎可以满足应用程序开发的所有需求,包括开发云原生应用程序。它是迄今为止使用最多的 Java 框架,它已经存在很多年了。它坚固可靠。背后的社区非常棒,愿意推动它向前发展,让它不断变得更好。技术和开发实践不断发展,Spring 非常善于跟上这一点。因此,在下一个云原生项目中使用 Spring 是一个很好的选择。 6 | 7 | 在本节中,我将重点介绍 Spring 全景的一些有趣特征。然后,我们开始创建一个 Spring Boot 应用程序。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/2.3.1-Introducing-Docker-Images-and-containers.md: -------------------------------------------------------------------------------- 1 | ### 2.3.1 Docker 介绍:镜像和容器 2 | 3 | 在机器上安装 Docker 软件时,您将获得 Docker 引擎包,其基于 `客户机/服务器` 体系结构。Docker 服务器(_Docker server_)包含 Docker 守护进程(_Docker daemon_),j是负责创建和管理 Docker 对象(如:镜像、卷、网络)的后台进程。Docker 服务器运行的机器称为 Docker 主机(_Docker Host_),要运行容器服务的计算机都是 Docker 主机,因此它具有正在运行的 Docker 守护进程。容器的可移植性是通过守护进程实现的。后续介绍中,我可能会混用 Docker 服务器和 Docker 守护进程。 4 | 5 | Docker 守护进程公开了一个 REST API,您可以使用它来发送指令。例如:运行容器或创建卷。Docker 客户端通过该 API 与守护进程对话。这个客户端是基于命令行的,可以通过以下两种方式与 Docker 守护进程交互:脚本(例如 Docker Compose)或直接通过 Docker CLI。 6 | 7 | 除了作为 Docker 引擎特征的客户机和服务器组件之外,另一个重要的平台元素是镜像中心(container registry),它具有与 Maven 存储库类似的功能。Maven 存储库用于托管和分发 Java 库,而镜像中心对容器镜像执行相同的操作。我们区分公共和私有注册中心。Docker 公司提供一个名为 Docker Hub([Hub.Docker.com](https://hub.docker.com/))的公共注册中心,这在本地 Docker 安装时是默认配置的,其中为许多常见的应用程序托管镜像,如 Ubuntu、PostgreSQL 和 OpenJDK。 8 | 9 | ![](../../assets/2.8.jpg) 10 | **图 2.8 显示了 Docker 客户端、Docker 服务器和镜像注册中心如何交互。** 11 | 12 | Docker 守护进程管理不同的对象。在本节中,我将重点介绍镜像和容器。 13 | 14 | 容器镜像(或者简单地说,镜像)是一个轻量级的可执行包,包括运行内部应用程序所需的一切。Docker 镜像格式是最常用的镜像格式,后来由开放容器计划(OCI)项目标准化成了 OCI 镜像。通过在 Dockerfile(一个包含生成镜像的所有步骤的,基于文本的文件)中定义指令,可以从头开始创建镜像。通常,镜像是基于另一个镜像的。例如,您可以在 OpenJDK 的基础上构建一个镜像。您可以添加一个 Java 应用程序。创建后,可以将镜像推送到像 DockerHub 这样的镜像中心。一个基本名称和标记用于标识每个镜像,其中标记通常是版本号。例如,版本 20.04 的 Ubuntu 镜像称为 Ubuntu:20.04。冒号用于分隔基本名称和版本。 15 | 16 | 容器是镜像的可运行实例。您可以从 Docker CLI 或 Docker Compose 管理容器生命周期:可以启动、停止、更新和删除容器。容器由它们所基于的基本镜像和启动时提供的配置定义(例如,用于自定义容器的环境变量)。默认情况下,容器之间,以及容器和主机之间是隔离的。但可以通过特定端口暴露服务,这通过端口转发(port forwarding)或端口映射(port mapping)来实现。容器可以有任意名称。如果未指定,Docker 服务器将分配一个随机的,像 bazinga_schrodinger。要运行容器,您需要 Docker 或任何其他与 OCI 标准兼容的容器运行时。 17 | 18 | 要运行新容器,可以使用 Docker CLI 与 Docker 守护进程进行交互,它检查指定的镜像是否已存在于本地服务器中。若不存在,将在注册中心查找并下载镜像,然后运行。整个工作流程,同样,如图 2.8 所示。 19 | 20 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/2.3.2-Running-a-Spring-application-as-a-container.md: -------------------------------------------------------------------------------- 1 | ### 2.3.2 运行 Spring 应用容器 2 | 3 | 让我们回到 Catalog Service,看看如何将其作为容器运行。有很多不同的方法可以实现这一目标。在这里,您将使用开箱即用的 Spring Boot 与 Cloud Native BuildPack。Cloud Native BuildPack 是一个由 Heroku 和 Pivotal 发起的项目,现在由 CNCF 托管。可以自动将应用程序源代码转换为容器镜像,而不是使用低级别的 Dockerfile。 4 | 5 | Paketo Buildpacks(一种 Cloud Native Buildpacks 的实现)与 Spring Boot 插件完全集成,适用于 Gradle 和 Maven。这意味着您可以容器化您的 Spring Boot 应用程序,而无需下载任何其他工具,无需任何额外的依赖项,也不需要编写 Dockerfile。 6 | 7 | 第 6 章将描述 Cloud Native Buildpacks 项目如何工作,以及如何配置它进行容器化 Spring Boot 应用程序。现在,我将给简单您演示下使用方法。 8 | 9 | 打开终端窗口,导航到 Catalog Service 项目的根文件夹,然后运行 bootBuildImage Gradle 任务。这就会使用 Cloud Native Buildpacks 将应用程序打包为容器镜像。 10 | 11 | ```text 12 | $ ./gradlew bootBuildImage 13 | ``` 14 | 15 | 第一次运行任务时,会需要一段时间来下载 BuildPack 创建容器镜像用到的软件包。第二次,只需要几秒钟。默认情况下,生成的镜像将命名为 catalog service:0.0.1-SNAPSHOT (`<工程名>:<版本>`)。您可以运行以下命令来获取新创建的镜像。 16 | 17 | ```bash 18 | $ docker images catalog-service:0.0.1-SNAPSHOT 19 | REPOSITORY TAG IMAGE ID CREATED SIZE 20 | catalog-service 0.0.1-SNAPSHOT 9318f716bfc4 41 years ago 277MB 21 | ``` 22 | 23 | >注意:您可能从上面命令的输出中发现,这个镜像好像是 41 年前生成的。这是 Cloud Native Buildpacks 的约定,以实现可重复的构建。后续执行构建的命令,如果在输入中没有任何更改,build 命令应该给出相同的输出。使用实际的创建时间戳要实现这一点是不可能的,因此 Cloud Native Buildpacks 使用约定的时间戳(1970 年 1 月 1 日)。 24 | 25 | 最后一件事就是运行镜像,并验证容器化应用程序是否仍然工作正常。打开终端窗口并运行以下命令。 26 | 27 | ```bash 28 | $ docker run --rm --name catalog-service -p 8080:8080 catalog-service:0.0.1-SNAPSHOT 29 | ``` 30 | 31 | 有关该命令的说明,请参考图 2.9。 32 | 33 | ![](../../assets/2.9.jpg) 34 | 35 | **图 2.9 从镜像启动容器化 web 应用程序的 Docker 命令。** 36 | 37 | 打开一个浏览器窗口,导航到 localhost:8080/ 并确认您仍然获得相同的问候返回。 38 | 39 | ```text 40 | Welcome to the book catalog! 41 | ``` 42 | 43 | 完成后,使用 `Ctrl+C` 停止容器。 44 | 45 | 在第 6 章中,您将进一步了解 Docker 的工作原理,以及如何从 Spring 启动应用程序,还有如何使用容器注册中心。我还将向您展示如何使用 Docker Compose 而不是 Docker CLI 来管理容器。在此之前,如果您想尝试使用容器,我给您留下一个有用的命令列表来控制容器的生命周期(表 2.2)。 46 | 47 | **表 2.2 用于管理镜像和容器的有用 Docker CLI 命令。** 48 | 49 | | Docker CLI 命令 | 作用 | 50 | | :--- | :--- | 51 | | docker images | 显示所有镜像 | 52 | | docker ps | 显示运行中的容器 | 53 | | docker ps -a | 显示所有容器,无论状态是运行还是终止 | 54 | | docker start | 运行容器 | 55 | | docker stop | 停止容器 | 56 | | docker rm | 移除终止的容器 | 57 | | docker rmi | 移除镜像 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 2.3 使用 Docker 容器化应用 2 | 3 | Catalog Service 应用程序可以运行了。在将其部署到云中之前,您应该对它进行容器化,这是为什么呢?容器提供了与周围环境的隔离,并具有应用程序运行所需的所有依赖项。在我们的例子中,大多数依赖项由 Gradle 管理,并与应用程序打包在一起(JAR 制品)。但 Java 运行时并非如此。将应用程序容器化,意味着它将独立且可跨任何云环境进行移植。如果没有容器,您需要在您想要部署应用程序的计算机上安装 JRE 17(您的应用程序正在使用的版本)。使用容器,您可以用标准方式管理所有应用程序,而不管应用使用的是何种语言和何种框架。 4 | 5 | Docker 是 Linux 容器最常用的实现。在 Docker 网站上([www.docker.com](https://www.docker.com)),您可以找到适用您本地环境的 Docker 设置说明,包括 macOS、Linux 或 Windows。对于 macOS 和 Windows,您可以下载 `Docker Desktop` 应用程序。对于Linux,您可以找到在多个发行版上安装 Docker 的说明。一旦您设置好了 Docker,您就可以继续探索它是如何工作的,以及如何使用它运行容器化的 Spring Boot 应用程序。 6 | 7 | > macOS 和 Windows 上的 Docker 是如何工作的? 8 | > 在上一章中,您了解到容器共享相同的操作系统内核并依赖于 Linux 特性,如 namespaces 和 cGroup。我们将在 Linux 的 Docker 容器中运行 Spring Boot 应用程序,但 Docker 也能在 macOS 或 Windows 机器上工作吗? 9 | > 当您在 Linux 操作系统上安装 Docker 时,您将获得完整的 Linux 主机上的 Docker 引擎软件。相反,如果您安装 Docker Desktop for Mac 或 Docker Desktop for Windows,只有 Docker 客户端安装在 macOS/Windows 主机上。在此场景中,会配置一个轻量级 Linux 虚拟机,Docker 服务器组件安装在该虚拟机上。作为使用者,您将获得几乎与 Linux 机器上相同的体验,也几乎不会注意到差别。但实际上,无论何时使用 Docker CLI 执行操作时,您实际上是在与一台虚拟机上的 Docker 服务器进行交互(即运行 Linux 的虚拟机)。 10 | > 您可以通过启动 Docker 并运行 `docker version` 命令来验证它。如图 2.7 所示,您会注意到 Docker 客户端正在 darwin/amd64 体系结构(在 macOS 上)或 windows/amd64 (在 Windows 上)上运行,而 Docker 服务器在 linux/amd64 上运行。 11 | > ![](../../assets/2.7.jpg) 12 | > **图 2.7 在 macOS/Windows 上,Docker 客户端组件在您的计算机上运行,而服务器运行在轻量级 Linux 虚拟机上。** 13 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/2.4.1-Introducing-Kubernetes-Deployments-pods-and-services.md: -------------------------------------------------------------------------------- 1 | ### 2.4.1 介绍 Kubernetes 的 Deployment、Pod 和 Service 2 | 3 | Kubernetes 是由 CNCF 托管的开源容器编排器。经过几年发展后,已经成为容器编排最常用的解决方案,所有主要云服务商都支持通过 Kubernetes 提供服务。Kubernetes 可以在桌面、数据中心、内部部署、云计算甚至物联网设备上运行。 4 | 5 | 在容器拓扑中,您只需要一台带有 Docker 守护进程的机器。使用 Kubernetes,您可以切换到编排器拓扑,这意味着您需要集群。Kubernetes 集群(_cluster_)是一组运行容器化应用程序的工作机器(节点,_Node_)。每个集群至少有一个工作节点。使用 kind,您可以在本地计算机上轻松创建单节点集群。在生产环境,您将使用由云平台(_Azure Kubernetes Service_)管理的集群。 6 | 7 | Kubernetes 集群由称为 `工作节点`(_worker nodes_)的机器组成,您在这些机器上部署应用程序。它们提供诸如 CPU、内存、网络和存储等能力,来支持容器运行,并将容器连接到网络。 8 | 9 | `控制面板`(_control plane_)是管理工作节点的容器编排层。它暴露用于定义、部署和管理容器生命周期的 API 和接口。它提供了所有实现编排功能的基本元素,如集群管理、定时和健康监测。 10 | 11 | 您可以通过 CLI 客户端 kubectl 与 Kubernetes 交互,该客户端与 `控制面板 ` 通讯以在 `工作节点` 上执行某些操作。客户端不与 `工作节点` 直接连接。图 2.11 显示了 Kubernetes 组件体系结构。 12 | 13 | ![](../../assets/2.11.jpg) 14 | **图 2.11 Kubernetes 的主要组件是 API、`控制面板` 和 `工作节点`。** 15 | 16 | Kubernetes 可以管理许多不同的 `对象` (_object_),无论是内置的还是自定义的。在本节中,您将使用 Pod、Deployment 和 Service。 17 | 18 | * Pod。最小的可部署单元。它可以包括一个或多个容器。通常是一个 Pod 仅包含一个应用程序,并且可能包含支持主应用程序的其他容器(例如,提供日志记录或要在初始化步骤中运行的管理任务)。Kubernetes 管理 Pod 而不是直接使用容器。 19 | * Deployment。它为 Kubernetes 提供了关于如何创建和更新应用实例的指南。对于每个实例,它都会创建一个 Pod。 20 | * Service。一个 Deployment(一组 Pod)可以定义为 Service,以公开给集群中的其他节点或外部使用者。 21 | 22 | >注意:在本书中,我将用大写字母拼写 Kubernetes 资源对象。当相同的词与术语一起使用时,以便将它们区分开来。例如,我在引用应用程序时使用服务,而我用 Service 时,我指的是 Kubernetes 对象。 23 | > 24 | >译者注:中文没有这个问题。我们把 Kubernetes Service 对象仍然使用 Service 一词,并不直接翻译成 `服务`。 25 | 26 | 当您想要运行一个新的应用程序时,您可以定义一个 `资源清单` (_resource manifest_),它描述应用程序所需的状态,例如,应复制 5 次并通过 8080 端口暴露服务。`资源清单` 通常使用 YAML。然后,使用 kubectl 客户端通过 `控制面板` 创建 `资源清单` 描述的相关资源。最后, `控制面板` 使用其内部组件处理请求,并最终在 `工作节点` 中创建资源。 `控制面板` 依赖容器注册中心获取 `资源清单` 中定义的镜像。工作流程同样如图 2.11 所示。 27 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/2.4.2-Running-a-Spring-application-on-Kubernetes.md: -------------------------------------------------------------------------------- 1 | ### 2.4.2 在 Kubernetes 是运行 Spring 应用 2 | 3 | 让我们回到 `极地书店` 项目。在上一节中,您容器化了 Catalog Service 应用程序。现在,是使用 Kubernetes 将其部署到集群的时候了。您已在本地环境中启动并运行了集群,现在需要的是 `资源清单`。 4 | 5 | 与 Kubernetes 交互的标准方式是通过声明式指令,您可以在 YAML 或 JSON 文件中定义。我将在第 7 章中向您展示如何编写 `资源清单`。在此之前,您将像前面使用 Docker 一样使用 Kubernetes CLI。 6 | 7 | 首先,您需要告诉 Kubernetes 从容器镜像部署 Catalog Service。您以前构建过一个(Catalog Service:0.0.1-SNAPSHOT)。默认情况下,kind 使用 Docker 注册中心来提取镜像,现在还无法访问您的本地镜像。因此,现在找不到 Catalog Service 应用程序构建的镜像。但不要担心:您可以手动将其导入本地集群。 8 | 9 | 打开终端窗口,并运行以下命令。 10 | 11 | ```bash 12 | $ kind load docker-image catalog-service:0.0.1-SNAPSHOT 13 | ``` 14 | 15 | 部署单元将是一个 Pod,但您不会直接管理 Pod。相反,您需要让 Kubernetes 来处理。Pod 是应用程序实例,因此它们的生命是短暂的。为了实现云原生目标,您希望平台负责实例化 Pod,以便任何一个坏了,随时可以换成另一个。您需要的是一个 Deployment 指示 Kubernetes 创建作为 Pod 资源的应用程序实例。 16 | 17 | 在终端窗口中,运行以下命令。 18 | 19 | ```bash 20 | $ kubectl create deployment catalog-service --image=catalog-service:0.0.1-SNAPSHOT 21 | ``` 22 | 23 | 有关该命令的说明,请参考图 2.12。 24 | 25 | ![](../../assets/2.12.jpg) 26 | 27 | **图 2.12 从容器镜像创建一个 Deployment 的 Kubernetes 命令。Kubernetes 将为应用程序创建 Pod。** 28 | 29 | 您可以按如下方式验证 Deployment 对象的创建。 30 | 31 | ```bash 32 | $ kubectl get deployment 33 | NAME READY UP-TO-DATE AVAILABLE AGE 34 | catalog-service 1/1 1 1 7s 35 | ``` 36 | 37 | 在幕后,Kubernetes 为 Deployment 中定义的应用程序创建了一个 Pod 资源,您可以按如下方式验证 Pod 对象的创建。 38 | 39 | ```bash 40 | $ kubectl get pod 41 | NAME READY STATUS RESTARTS AGE 42 | catalog-service-7fff49dd77-9cnd7 1/1 Running 0 21s 43 | ``` 44 | 45 | 默认情况下,无法访问在 Kubernetes 中运行的应用程序。让我们来解决这个问题。首先,您可以通过运行以下命令,在集群中公开 Catalog Service 服务资源。 46 | 47 | ```bash 48 | $ kubectl expose deployment catalog-service --name=catalog-service --port=8080 49 | ``` 50 | 51 | 有关该命令的说明,请参考图 2.13。 52 | 53 | ![](../../assets/2.13.jpg) 54 | 55 | **图 2.13 使用 Kubernetes 命令将 Deployment 作为 Service 公开。Catalog Service 应用程序将通过端口 8080 向集群网络公开。** 56 | 57 | Service 对象向集群内的其他组件公开应用程序。您可以使用以下命令核实一下是否已正确创建它。 58 | 59 | ```bash 60 | $ kubectl get service 61 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 62 | catalog-service ClusterIP 10.96.141.159 8080/TCP 7s 63 | ``` 64 | 65 | 然后,您可以将流量从计算机上的本地端口(例如 8000)转发到集群内服务公开的端口(8080)。还记得 Docker 中的端口映射 8080 吗?其工作原理相似。命令的输出将告诉您端口转发是否正确配置。 66 | 67 | ```bash 68 | $ kubectl port-forward service/catalog-service 8000:8080 69 | Forwarding from 127.0.0.1:8000 -> 8080 70 | Forwarding from [::1]:8000 -> 8080 71 | ``` 72 | 73 | 有关该命令的说明,请参考图 2.14。 74 | 75 | ![](../../assets/2.14.jpg) 76 | 77 | **图 2.14 Kubernetes 命令,用于将端口请求从本地主机转发到集群中的 Service 上。Catalog Service 应用程序通过端口 8000 公开给本地主机。** 78 | 79 | 现在,每当您访问本地主机上的端口 8000 时,请求将被转发到集群内的 Service 中,负责公开 Catalog Service 应用程序。打开浏览器窗口中,导航到 localhost:8000/(确保使用 8000 而不是 8080)并确认您仍然收到与以前相同的问候语。 80 | 81 | ```text 82 | Welcome to the book catalog! 83 | ``` 84 | 85 | 非常好!您从打包为 JAR 文件的 Spring Boot 应用程序开始。然后使用 Cloud Native Buildpacks 将其封装并在 Docker 上运行。最后,您用 Kubernetes 将应用程序部署到集群。当然,这是一个本地集群,但它也可以是任何远程云端集群。这个过程的美妙之处在于它独立于环境,以同样的方式工作。您可以使用相同的方法来部署 Catalog Service 到任何云基础架构中的集群中。这不是很棒吗? 86 | 87 | 在第 7 章,您将更多的使用 Kubernetes。现在,请使用 `Ctrl+C` 终止端口转发。使用 kubectl 删除 Service (kubectl delete service catalog-service),删除 Deployment (kubectl delete deployment catalog-service)。最后,您可以删除集群(kind delete cluster)。如果您想使用 Kubernetes 做一些实验,我在这里给您列举了一些有用的命令(表 2.3)。 88 | 89 | **表 2.3 用于管理 Pod、Deployment 和 Service 的 Kubernetes CLI 命令。** 90 | 91 | | Kubernetes CLI 命令 | 作用 | 92 | | :--- | :--- | 93 | | kubectl get deployment | 显示所有 Deployment | 94 | | kubectl get pod | 显示所有 Pod | 95 | | kubectl get svc | 显示所有 Service | 96 | | kubectl delete deployment | 删除指定 Deployment | 97 | | kubectl delete pod | 删除指定 Pod | 98 | | kubectl delete svc | 删除指定 Service | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 2.4 使用 Kubernetes 管理容器 2 | 3 | 到目前为止,您已经使用 Spring Boot 构建了一个 web 应用程序(Catalog Service),使用 Cloud Native Buildpacks 将其容器化,并使用 Docker 运行它。要完成 `极地书店` 试点项目全过程,您还差最后一步:将应用程序部署到云。 4 | 5 | 您将使用 Kubernetes,它已成为容器编排的事实标准。我将在后面的章节中详细介绍这个主题,但我想让您先体验一下 Kubernetes 的工作方式,以及如何使用它部署 web 应用程序。 6 | 7 | Kubernetes(通常简称为 K8s )是一个用于自动化部署、扩容和管理容器化应用程序的开源系统([kubernetes.io](https://kubernetes.io/))。当使用 Docker 中的容器时,您的部署目标是一台机器,在前面的示例中也就是您的电脑。在其他场景中,它可能是一个虚拟机(VM)。无论如何,都是将容器部署到特定机器上。如果您需要多台机器应该怎么办呢?当要在不停机的情况下部署容器、利用云来弹性扩容、跨不同的主机连接它们,您需要的就不仅仅是容器引擎。 8 | 9 | 这样,部署目标就从特定计算机转移到计算机集群。Kubernetes 可以为您管理一组计算机。我在上一章介绍拓扑结构时,谈到了这一区别。图 2.10 再次提醒您容器部署拓扑和编排器部署拓扑的不同部署目标。 10 | 11 | ![](../../assets/2.10.jpg) 12 | **图 2.10 容器的部署目标是一台机器,而对于编排器来说,它是一个集群。** 13 | 14 | 有几种方法可以在本地环境中安装 Kubernetes。方法一是建议安装 Kind,这是一个使用 Docker 容器运行本地 Kubernetes 集群的工具。因为您已经在本地机器上安装了 Docker,所以这是一种方便获得本地 Kubernetes 集群的方法。您可以在项目网站 [kind.sigs.k8s.io](https://kind.sigs.k8s.io/) 中找到安装指南。这也是我将在本书中使用的例子,但是如果您喜欢,可以自由选择其他工具。另一个可行的选择是 minikube ([minikube.sigs.k8s.io](https://minikube.sigs.k8s.io/))。 15 | 16 | 在继续后面内容之前,请确保 Docker 引擎在您的机器上正确运行,并且安装了管理本地 Kubernetes 集群的工具。如果您使用的是 kind,请打开终端窗口,并使用以下命令创建本地 Kubernetes 集群。 17 | 18 | ```bash 19 | $ kind create cluster 20 | ``` -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/2.5.1-Understanding-the-requirements-of-the-system.md: -------------------------------------------------------------------------------- 1 | ### 2.5.1 理解系统需求 2 | 3 | `极地书店` 是一家以传播有关北极和北极地区知识和信息为使命的专业书店,包括历史、地理、动物等等。管理图书馆的组织 Polarsophia 已决定开始在全球范围内在线销售图书。但这只是开始。这个计划雄心勃勃,整体愿景包括开发一整套软件产品来完成 Polarsophia 的商业目标。在一个成功的试点项目之后,该组织决定开始一次云原生之旅。 4 | 5 | 在本书中,您将构建一个系统的核心部分,该系统在以下方面具有无限的可能性:功能和集成。管理层计划在短时间内交付新功能,缩短上市时间,尽早获得用户反馈。目标是让书店与每个人、每个地方都很紧密相连。因此应用程序应该具有高度的可扩展性。全世界范围的大量用户以及高伸缩性,这样的系统需要高可用性,因此韧性至关重要。 6 | 7 | Polarsophia 是一个小型组织,他们需要优化成本。尤其是关于基础设施,他们负担不起建立自己的数据中心,所以他们决定租用来自第三方的硬件。 8 | 9 | 到目前为止,您可能已经认识到公司转向云计算的一些原因了。这就是 `极地书店` 应用程序的作用。当然,它将是一个云原生应用,书籍将通过该应用程序进行出售。当顾客购买一本书时,可以检查他们订单的状态。两类人将使用 `极地书店` 应用程序: 10 | 11 | * 客户可以浏览目录中的书籍,购买一本,并查看订单; 12 | * 员工可以管理书籍、更新现有书籍以及向目录中添加新项目。 13 | 14 | 图 2.15 描述了 `极地书店` 云原生系统的体系结构。如您所见,它由几个服务组成。有些将实现系统的业务逻辑,其他服务将实现共享服务,如配置中心。为了更清晰,该图没有显示有关安全和可观测相关的服务。您将在稍后的章节中熟悉它们。 15 | 16 | 在接下来的章节中,我将引导您更详细地浏览图 2.15 中的图表,添加有关特定服务的更多信息,在部署阶段采用不同的视角来观察系统。现在,让我们继续学习项目中使用的技术和模式。 17 | 18 | ![](../../assets/2.15.jpg) 19 | **图 2.15 `极地书店` 的架构。云原生系统包括应用程序和数据服务等具有不同职责的服务。为清楚起见,未显示安全性和可观测性相关服务。** 20 | 21 | 22 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/2.5.2-Exploring-patterns-and-technologies-used-in-the-project.md: -------------------------------------------------------------------------------- 1 | ### 2.5.2 工程中用到的技术和模式 2 | 3 | 每当我在书中介绍一个新话题时,将向您展示如何将前面讲过的技术或模式应用于 `极地书店` 项目。在本节中,我概述一下我们将要解决的主要问题,以及我们将使用哪些技术和模式来解决这些问题。 4 | 5 | #### 网络交互 6 | 7 | `极地书店` 包含多个服务,这些服务必须相互通信才能实现它们的功能。您将构建通过 HTTP 同步交互的 RESTful 服务。无论是以阻塞方式(传统 servlet)还是以非阻塞方式(响应式编程)。而且 SpringMVC 和 Spring WebFlux (在 Project Reactor 基础上)将是您实现这一结果的主要工具。 8 | 9 | 在构建云原生应用程序时,应该记住设计松散耦合的应用程序服务,并考虑如何在分布式系统上下文中保持数据一致性。在需要完成一项复杂功能时,会涉及很多的服务,同步通信可能会产生问题。这就是为什么事件驱动编程在云中越来越流行的原因:它让您克服了同步通信的难题。 10 | 11 | 我将向您展示如何使用事件和消息,来解耦服务并确保数据一致性。您将使用 Spring Cloud Stream 实现服务之间的数据流,以及 12 | Spring Cloud Function 将消息处理程序定义为函数。后一种方法可以自然地在部署到支持无服务的平台,如 Azure Function、AWS Lambda、Knative 等。 13 | 14 | #### 数据 15 | 16 | 数据是软件系统的重要组成部分。在 `极地书店` 系统中,您将使用关系型数据库 PostgreSQL 存储应用程序数据。我会演示如何使用 Spring Data JDBC (被动式)和 Spring Data R2DBC(响应式)将应用程序与数据源集成。然后,您将看到如何进一步优化数据源并使用 Flyway 管理迁移脚本。 17 | 18 | 云原生应用程序应该是无状态的,但状态需要存储在某个地方。在 `极地书店` 中,您将使用 Redis 将会话信息进行外部存储,保留应用程序无状态且可扩展。Spring Session 使实现集群用户传话变得容易。特别是,我将向您展示如何使用 Spring Session Data Redis 集成 web 会话管理。 19 | 20 | 除了持久化数据和会话之外,您还将实现事件驱动编程模式。Spring AMQP 和 RabbitMQ 将是要使用的技术。 21 | 22 | 在本地,您将在 Docker 容器中运行这些数据服务。在生产中,使用 Azure Kubernetes Service(AKS),您将依赖云服务商提供的托管服务,它解决了高可用性、集群、存储和数据复制等关键问题。 23 | 24 | #### 配置 25 | 26 | 在本书中,我将向您展示如何在不同的环境中配置 `极地书店` 中的服务。首先,我将探讨 Spring Boot 提供的 properties 和 profile,以及何时使用它们。然后,您将学习将 Spring 应用程序作为 JAR 在容器里运行时,如何使用环境变量作为外部配置。最后,我来教您如何在 Kubernetes 中使用 ConfigMaps 和 Secrets。您还将看到如何通过 Spring Cloud Config 进行集中配置管理,以及在运行时使用 Spring Cloud Bus 更新配置。 27 | 28 | #### 路由 29 | 30 | `极地书店` 是一个分布式系统,需要一些路由配置。Kubernetes 具有内置的服务发现功能,可帮助您将服务与物理地址和主机名分离。云原生应用程序是可伸缩的,因此服务之间的交互应该考虑到:要调用哪个实例呢?再一次,Kubernetes 为您提供了负载均衡功能,因此您无需在应用程序中再进行处理了。 31 | 32 | 我将指导您使用 Spring Cloud Gateway 实现一个服务,该服务将充当 API 网关,用于把任何内部 API 变化与外部隔离。它还将是一种边缘服务,将一次性解决跨领域的问题,如安全性和韧性。这样的服务将是 `极地书店` 的入口,必须高可用、性能良好,并且具有容错能力。 33 | 34 | #### 可观测性 35 | 36 | `极地书店` 系统中的服务必须是可观测的,这才是云原生服务。我将向您展示如何使用 Spring Boot Actuator 设置健康和信息端点,并公开相关度量给 Prometheus 进行提取并处理。然后您将使用 Grafana 可视化最关键的指标,并显示在仪表板中。 37 | 38 | 请求可以由多个服务处理,因此需要分布式链路跟踪,跟踪从一个服务到另一个服务的请求流。您会和我一起设置 Spring Cloud Sleuth。然后,Grafana Tempo 将提取、处理并可视化整个链路,让您可以完整地了解系统是如何完成其功能的。 39 | 40 | 最后,我们需要一个适当的日志策略。我们应该将日志作为事件流处理,因此让您的 Spring 应用程序将日志事件流化为标准输出,而不考虑它们是如何处理或存储的。Fluent Bit 将负责从所有服务收集日志,Grafana Loki 将存储和处理它们,Grafana 将允许您查询日志。 41 | 42 | #### 韧性 43 | 44 | 云原生应用程序应该具有韧性。对于 `极地书店` 项目,我将向您展示使用 Project Reactor、Spring Cloud Circuit Breaker 以及 Resilience4J 等使应用程序具有韧性的各种技术,用于实施断路器、重试、超时和其他模式。 45 | 46 | #### 安全 47 | 48 | 安全是一个广泛的主题,我在本书中无法深入讨论。不过,我还是会简单讨论这个主题,因为它是当今最关键的软件关注点之一。这是一个从项目一开始就应持续关注并解决的普遍问题,并且不能掉以轻心。 49 | 50 | 对于 `极地书店`,我将向您展示如何将身份验证和授权功能添加到云原生应用程序中。您将看到如何保护服务之间,以及用户和应用程序间的通信。您将依靠 OAuth 2.0 和 OpenID Connect 来实现这些功能。Spring Security 支持这些标准,可以无缝集成以提供身份验证和授权。您将使用 Keycloak 进行身份和访问控制管理。 51 | 52 | 此外,我还将介绍密钥管理和加密的概念。当然也不能非常深入讨论这些主题。但我将向您展示如何管理机密来配置 Spring 服务(直接使用配置服务器和 Kubernetes 时)。 53 | 54 | #### 测试 55 | 56 | 自动化测试对于云原生应用程序的成功至关重要。自动化测试将在几个级别覆盖 `极地书店` 应用程序。我将向您展示如何使用 JUnit5 57 | 编写单元测试。Spring Boot 添加了许多方便的实用程序来改进集成测试,您将使用它们来确保您的服务质量。您将为各种 `极地书店` 功能编写测试类,包括 REST 端点、消息流和数据集成和安全性。 58 | 59 | 保持跨环境的对等性,对于确保应用程序的质量至关重要。尤其是在支持服务方面。在生产中,您将使用的服务是 PostgreSQL 和 Redis。在测试期间,您应该使用类似的服务,而不是模拟或者特定于测试的工具,如内存中的 H2 数据库。Testcontainers 框架将帮助您使用真实服务进行自动化测试。 60 | 61 | #### 构建和部署 62 | 63 | `极地书店` 的主要服务是使用 Spring。您将看到如何打包 Spring 应用程序,将其作为 JAR 文件运行,使用 Cloud Native Buildpacks 对其进行容器化,使用 Docker 运行,最后,您将使用 Kubernetes 部署容器。您还将看到如何使用 Spring Native 和 GraalVM 将 Spring 应用程序编译为本机镜像,并在无服务器架构中使用它们。利用无服务器的即时启动、即时峰值性能、减少内存消耗、减少图像大小。然后,您将在托管服务器上部署它们,基于 Knative(Google Cloud Run)的无服务器平台。 64 | 65 | 我将向您展示如何通过 GitHub Actions 设置部署流水线(CI/CD)来自动化构建。流水线将在每次提交时构建应用程序,运行测试,然后打包以备部署。这种自动化将是向客户持续交付文化的一部分,快速可靠地为客户带来价值。最后,您还将使用 GitOps 在 Azure Kubernetes 服务(AKS)上自动部署 `极地书店` 到 Kubernetes 群集。 66 | 67 | #### UI 68 | 69 | 这本书的重点是后端技术,所以我不会教您任何前端内容。当然,您的应用程序需要一个前端,以便用户与之交互。 `极地书店` 将依赖使用 Angular 框架的客户端应用程序。我不会在本书中展示 UI 应用程序代码,因为它超出了本书的范围,但我会将相关代码放在本书附带的代码存储库中。 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 2.5 云原生应用 —— `极地书店` 2 | 3 | 我写这本书的目的是尽可能多地为您提供真实世界的代码示例。现在您已经探索了一些关键概念,并尝试了构建、容器化和部署 Spring 应用程序。让我们承担一个稍微复杂的任务:一家在线书店。我将指导您完成云原生系统的开发,直到将其部署到公有云上的 Kubernetes 集群。 4 | 5 | 对于以下章节中涉及的每个概念,我将向您展示如何将其应用于真实的云原生场景,提供完整的动手学习体验。记住本书附带的所有的代码都可以在 GitHub 存储库中获得。 6 | 7 | 本节将定义您将构建的云原生项目的需求,并描述其功能和架构。然后我将介绍实现它的主要技术和模式。 8 | 9 | 在本书的最后,您将基于 Spring 构建一个完整的云原生应用程序,将其容器化,并将其署到公有云 Kubernetes 中。 10 | -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/Introduction.md: -------------------------------------------------------------------------------- 1 | # 第 2 章 云原生模式和技术 2 | 3 | 本章内容 4 | 5 | * 理解云原生应用程序的开发原则 6 | * 使用 Spring Boot 构建云原生应用程序 7 | * 使用 Docker 和 BuildPack 容器化应用程序 8 | * 使用 Kubernetes 将应用程序部署到云 9 | * 介绍本书中使用的模式和技术 10 | 11 | 我们为云而设计应用程序的方式与传统方法不同。`十二要素(Twelve-Factor)` 方法被视为云原生应用程序的最佳实践和开发模式。我将在本章第一部分介绍这种方法论,本书后续章节将进行详细介绍。 12 | 13 | 然后我们将构建一个简单的 Spring Boot 应用程序,并使用 Java、Docker 和 Kubernetes 运行它,如图 2.1 所示。在本书中,我将深入探讨这些主题,所以在开始的时候,如果有些东西不完全清楚,请不要担心。本章旨在让您熟悉在云环境中,从开发到生产的整个过程,也让您了解使用到的模式和技术。 14 | 15 | ![](../assets/2.1.jpg) 16 | **图 2.1 Spring 应用程序从 Java 到容器再到 Kubernetes 的过程。** 17 | 18 | 最后,我将向您介绍基于 Spring 和 Kubernetes 的云原生项目,我们后续将会一章又一章地进行开发。我们会使用到在第一部分提到的这些云原生应用的属性和模式。 -------------------------------------------------------------------------------- /cn-translate/02-Cloud-native-patterns-and-technologies/Summary.md: -------------------------------------------------------------------------------- 1 | ## 2.6 总结 2 | 3 | * 构建云原生应用程序的良好起点是 `十五要素` 方法论。它确定了开发原则,以提供跨执行环境的最大可移植性,适合部署在云平台,方便扩展,保证开发和生产环境之间的一致性,并可实现持续交付。 4 | * Spring 是一个套件,它提供了构建现代应用的所有常用功能。核心是 Spring 框架,提供的应用程序上下文,在整个生命周期中管理 bean 和属性。 5 | * Spring Boot 为加快云原生开发奠定了基础。可快速构建生产就绪的应用程序,包括嵌入式服务器、自动配置、监控和容器化等功能。 6 | * Docker 是一种创建容器的技术。我们将 Spring 应用程序封装为容器,可跨环境移植,并对其运行时依赖关系有更多的控制。 7 | * 容器镜像是轻量级的可执行包,其中包含了在内部运行应用程序所需的所有内容。Spring Boot 应用程序可以使用 Cloud Native Buildpacks 打包为镜像。 8 | * 通常在云原生系统中,您需要处理多个容器,管理如此复杂的系统需要一种方法。Kubernetes 提供了以下功能:协调、安排和管理容器。 9 | * Kubernetes Pod 是最小的部署单位。Kubernetes Deployment 描述如何从容器镜像开始,将应用程序实例创建为 Pod。Kubernetes Service 允许您在集群外部公开应用程序端点。 10 | 11 | 12 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/3.1.1-One-codebase-one-application.md: -------------------------------------------------------------------------------- 1 | # 3.1.1 一份基准代码对应一个应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/3.1.2-Dependency-management-with-Gradle-and-Maven.md: -------------------------------------------------------------------------------- 1 | # 3.1.2 使用 Maven 或 Gradel 管理依赖 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/Introduction.md: -------------------------------------------------------------------------------- 1 | # 3.1 创建云原生项目 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.1-Executable-JARs-and-embedded-servers-Ready-for-the-cloud.md: -------------------------------------------------------------------------------- 1 | # 3.2.1 可执行 JAR 和内嵌服务:为云做好准备 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.2-Understanding-the-thread-per-request-model.md: -------------------------------------------------------------------------------- 1 | # 3.2.2 理解 一个请求一个线程 模式 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.3-Configuring-the-embedded-Tomcat.md: -------------------------------------------------------------------------------- 1 | # 3.2.3 配置内嵌 Tomcat 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/Introduction.md: -------------------------------------------------------------------------------- 1 | # 3.2 使用内嵌服务器 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.1-REST-API-first-business-logic-later.md: -------------------------------------------------------------------------------- 1 | # 3.3.1 REST API 第一,业务逻辑第二 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.2-Implementing-a-REST-API-with-Spring-MVC.md: -------------------------------------------------------------------------------- 1 | # 3.3.2 使用 Spring MVC 实现 REST API 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.3-Data-validation-and-error-handling.md: -------------------------------------------------------------------------------- 1 | # 3.3.3 数据校验和出错处理 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.4-Evolving-APIs-for-future-requirements.md: -------------------------------------------------------------------------------- 1 | # 3.3.4 为未来需求扩展 API 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/Introduction.md: -------------------------------------------------------------------------------- 1 | # 3.3 使用 Spring MVC 构建 RESTful 应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.1-Unit-tests-with-JUnit-5.md: -------------------------------------------------------------------------------- 1 | # 3.4.1 使用 JUnit 5 进行单元测试 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.2-Integration-tests-with-SpringBootTest.md: -------------------------------------------------------------------------------- 1 | # 3.4.2 使用 @SpringBootTest 进行集成测试 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.3-Testing-REST-controllers-with-WebMvcTest.md: -------------------------------------------------------------------------------- 1 | # 3.4.3 使用 @WebMvcTest 测试 REST 控制器 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.4-Testing-the-JSON-serialization-with-JsonTest.md: -------------------------------------------------------------------------------- 1 | # 3.4.4 使用 @JsonTest 测试 JSON 序列化 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/Introduction.md: -------------------------------------------------------------------------------- 1 | # 3.4 使用 Spring 测试 RESTful 应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.5-Continuous-integration-pipelines-with-GitHub-Actions/3.5.1-GitHub-Actions-Automating-builds-and-tests.md: -------------------------------------------------------------------------------- 1 | # 3.5.1 使用 GitHub Action 进行自动构建和测试 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/3.5-Continuous-integration-pipelines-with-GitHub-Actions/Introduction.md: -------------------------------------------------------------------------------- 1 | # 3.5 使用 GitHub Action 进行持续集成 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/Introduction.md: -------------------------------------------------------------------------------- 1 | # 第 3 章 进行云原生应用开发 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/03-Getting-started-with-cloud-native-development/Summary.md: -------------------------------------------------------------------------------- 1 | # 3.6 总结 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/4.1.1-Properties-Key-value-pairs-for-configuration.md: -------------------------------------------------------------------------------- 1 | ### 4.1.1 Properties:键值对 2 | 3 | Properties (属性)是 Java 支持的键/值对,是 `java.util.Properties` 的一等公民。它们在 Java 应用程序中扮演着重要角色,可以在编译的 Java 代码之外存储配置参数,还可以从 Spring Boot 不同来源自动加载。当在多个来源中都定义了同一属性时,有规则决定哪一个优先。例如,如果在属性文件和命令行参数中,都指定了 server.port 属性,则后者优先于前者。以下是一些属性来源的优先级列表,从具有最高优先级的来源开始。完整的列表您可以参考 Spring Boot 文档([Spring.io/projects/Spring-boot](https://spring.io/projects/spring-boot))。 4 | 5 | 1. 添加了 @TestPropertySource 的测试类。 6 | 1. 命令行参数。 7 | 1. 来自 System.getProperties() 的 JVM 系统属性。 8 | 1. 来自 System.getenv() 的 OS 环境变量。 9 | 1. 配置数据文件。 10 | 1. `@Configuration` 类上的 PropertySource 注解。 11 | 1. SpringApplication.setDefaultProperties 的默认属性。 12 | 13 | 配置数据文件可以进一步划分优先级,从优先级最高的开始。 14 | 1. JAR 文件外,application-{profile}.properties 和 application-{profile}.yml 中,特定于配置文件的属性。 15 | 1. JAR 文件外,application.properties 和 application.yml 中的应用程序属性。 16 | 1. JAR 文件内,application-{profile}.properties 和 application-{profile}.yml 中,特定于配置文件的属性。 17 | 1. JAR 文件内,application.properties 和 application.yml 中的应用程序属性。 18 | 19 | Spring 中属性处理的美妙之处在于,您不需要从特定来源获取值。Environment 抽象允许您通过统一的接口,访问任何源中定义的任何属性。如果在多个源中定义了相同的属性,则返回优先级最高的。您甚至可以添加自己的自定义源并为其指定优先级。 20 | 21 | >注意:Spring 内置了使用 Properties 格式定义属性的支持。除此之外,Spring Boot 还支持使用 YAML 格式。YAML 是 JSON 的超集,提供了比 Properties 更灵活的格式。官方网站([yaml.org](https://yaml.org/))将 YAML 描述为“适用于所有编程语言的,人性化的数据序列化标准”。在您的应用程序中,您可以随意选择其中一种。本书中的所有示例都将使用 YAML。 22 | 23 | #### 使用应用程序属性 24 | 25 | 有几种方法可以从 Java 类访问属性,如图 4.3 所示。最通用的方法基于 Environment 接口,当您需要访问应用程序属性时可以自动注入。例如,您可以使用它来访问 server.port 属性,按如下所示。 26 | 27 | ```java 28 | @Autowired 29 | private Environment environment; 30 | 31 | public String getServerPort() { 32 | return environment.getProperty("server.port"); 33 | } 34 | ``` 35 | 36 | ![](../../assets/4.3.jpg) 37 | **图 4.3 您可以通过不同的方式访问 Spring 属性。** 38 | 39 | 也可以注入属性,而无需显式调用 Environment 对象。就像使用 @Autowired 注解注入 Spring bean 一样,您可以应用 `@Value` 注解以插入属性值。 40 | 41 | ```java 42 | @Value("${server.port}") 43 | private String serverPort; 44 | 45 | public String getServerPort() { 46 | return serverPort; 47 | } 48 | ``` 49 | 50 | 您可以使用属性配置应用程序,而无需在代码中硬编码属性值,这是我们的目标之一。但在使用 Environment 对象或 `@Value` 注解时,仍然有一个难以管理的硬编码值:属性的键。更健壮的可维护选项(也是 Spring 团队推荐的选项)是使用特殊的,用注解 `@ConfigurationProperties` 标记的 bean 保存配置数据。在学习如何定义自定义属性的同时,您将在下一节中探索此功能。 51 | 52 | 53 | #### 定义自定义属性 54 | 55 | Spring Boot 附带了大量属性来配置应用程序的各个方面,取决于您在项目中导入的 starter 依赖项。不过,迟早您会需要定义自己的属性。 56 | 57 | 让我们考虑一直在做的 Catalog Service。在第 2 章中,您定义了 HTTP 端点向用户返回欢迎消息。我们现在有一个新的需求:欢迎消息应该是可配置的。这可能不是非常有用的功能,但它将帮助我向您展示不同的配置选项。 58 | 59 | 要做的第一件事,是告诉 Spring Boot 扫描应用程序上下文中的配置数据 Bean。您可以通过将 `@ConfigurationPropertiesScan` 注解添加到 Catalog Service 工程的 CatalogServiceApplication 类上。 60 | 61 | **清单 4.1 启用扫描配置数据 bean(CatalogServiceApplication.java)** 62 | ```java 63 | @SpringBootApplication 64 | @ConfigurationPropertiesScan ❶ 65 | public class CatalogServiceApplication { 66 | public static void main(String[] args) { 67 | SpringApplication.run(CatalogServiceApplication.class, args); 68 | } 69 | } 70 | ``` 71 | 72 | ❶ 在Spring上 下文中加载配置数据 bean。 73 | 74 | 然后,定义一个新的 com.polarbookshop.catalogservice.config 包,并创建一个 PolarProperties 记录(record)并添加 `@ConfigurationProperties` 注解,以将其标记为配置数据。`@ConfigurationProperties` 注解可配置前缀参数,前缀与字段名组合形成完整属性键。Spring Boot 将尝试映射所有具有该前缀的属性到类中的字段上。在本例中,只映射了一个属性:polar.greeting。 75 | 76 | **清单 4.2 在 Spring bean 中定义自定义属性(PolarProperties.java)** 77 | 78 | ```java 79 | package com.polarbookshop.catalogservice.config; 80 | 81 | import org.springframework.boot.context.properties.ConfigurationProperties; 82 | 83 | @ConfigurationProperties(prefix = "polar") ❶ 84 | public record PolarProperties( 85 | String greeting ❷ 86 | ){} 87 | ``` 88 | 89 | ❶ 将该类标记为以前缀 “polar”开头的配置属性源。 90 | 91 | ❷ 自定义“polar.greeting”(前缀+字段名)属性字段,会解析为字符串。 92 | 93 | 94 | 或者,您可以在 build.gradle 文件中添加对 Spring Boot Configuration Processor 的新依赖项。这将在构建时自动为新属性生成元数据,并存储在 META-INF/spring-configuration-metadata.json 中。IDE 可以提取它们,并帮助您进行自动补全和类型检查。记住在新添加后 刷新/重新导入 Gradle 依赖项。 95 | 96 | ```gradle 97 | configurations { ❶ 98 | compileOnly { 99 | extendsFrom annotationProcessor 100 | } 101 | } 102 | 103 | dependencies { 104 | ... 105 | annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' ❷ 106 | } 107 | ``` 108 | 109 | ❶ 将 Gradle 配置为在生成项目时使用注解处理器。 110 | 111 | ❷ 从自定义属性生成元数据。 112 | 113 | 然后,您可以通过构建项目(./gradlew build)触发元数据生成。这时,可以在 application.yml 为 polar.greeting 定义默认值。当插入新属性时,IDE 应为您提供自动补全和类型检查。 114 | 115 | ```yaml 116 | polar: 117 | greeting: Welcome to the local book catalog! 118 | ``` 119 | 120 | 在清单 4.2 中, greeting 字段将映射到 polar.greeting,这是您刚刚在 application.yml 中自定义的值。 121 | 122 | #### 使用自定义属性 123 | 124 | 用 `@ConfigurationProperties` 注解的类或记录(record)是标准的 Spring bean,所以可以在任何需要的地方直接注入。Spring Boot 初始化所有配置 bean,并使用任何支持的配置来源数据填充它们。对于 Catalog Service,数据来源于 application.yml 文件。 125 | 126 | Catalog Service 的新要求是,使根端点返回的欢迎消息。可通过 polar.greeting 属性进行配置。打开 HomeController 类,并更新处理方法,以从自定义属性而不是使用固定值来获取消息。 127 | 128 | **清单 4.3 使用配置 bean 中的自定义属性(HomeController.java)** 129 | 130 | ```java 131 | package com.polarbookshop.catalogservice.web; 132 | 133 | import com.polarbookshop.catalogservice.config.PolarProperties; 134 | import org.springframework.web.bind.annotation.GetMapping; 135 | import org.springframework.web.bind.annotation.RestController; 136 | 137 | @RestController 138 | public class HomeController { 139 | private final PolarProperties polarProperties; ❶ 140 | 141 | public HomeController(PolarProperties polarProperties) { 142 | this.polarProperties = polarProperties; 143 | } 144 | 145 | @GetMapping("/") 146 | public String getGreeting() { 147 | return polarProperties.greeting(); ❷ 148 | } 149 | } 150 | ``` 151 | 152 | ❶ 注入 bean 以访问自定义属性。 153 | 154 | ❷ 使用来自配置数据 bean 的欢迎消息。 155 | 156 | 您现在可以构建并运行应用程序,以验证它是否按预期工作(./gradlew bootRun)。然后,打开一个终端窗口,向 Catalog Service 公开的根端点发送 GET 请求。 157 | 158 | ```bash 159 | $ http :9001/ 160 | ``` 161 | 162 | 结果应该是您在 application.yml 中为属性 polar.greeting 配置的消息。 163 | 164 | ```text 165 | Welcome to the local book catalog! 166 | ``` 167 | 168 | >注意:与应用程序一起打包的属性文件,对于定义合理的默认值是非常有用的。它们还可以作为应用程序支持哪些配置属性的规范文件。 169 | 170 | 以下部分将介绍 Spring Environment 抽像类、profiles,以及如何将它们用于云原生应用程序。在继续后续内容之前,您可以使用 `Ctrl + C` 停止应用程序。 171 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/4.1.2-Profiles-Feature-flags-and-configuration-groups.md: -------------------------------------------------------------------------------- 1 | ### 4.1.2 Profiles:特性标志和配置分组 2 | 3 | 有时,您可能希望仅在特定的条件下将 bean 加载到 Spring 上下文中。例如,您可能希望定义一个负责生成测试数据的 bean,仅当在本地工作或测试应用程序时使用。Profiles 是加载 bean 的逻辑组,仅当指定的 Profile 处于活动状态时,才将其导入 Spring 上下文。您可以激活零、一或多个文件。所有未分配给 Profile 文件的 bean 都始终是激活状态。分配给默认 Profile 文件的配置,只有当没有指定 Profile 时,才会被激活。Spring Boot 扩展了这一概念到 Property 文件,允许定义一组配置,仅在特定 Profile 文件处于活动状态时才启用。 4 | 5 | 本节介绍了 Spring 中 profiles 的两种不同用例:特性标志和配置分组。 6 | 7 | #### 将 Profiles 用作特性标志 8 | 9 | 第一个用例是仅当指定的 Profile 文件处于活动状态时才加载一组配置 bean。部署环境不应该对分组背后的推理产生太大的影响。一个常见的错误是使用像 dev 或 prod 这样的 Profile 文件有条件地加载 bean。如果您这样做,应用程序将与环境耦合,通常不是我们想要的云原生应用程序。 10 | 11 | 考虑将应用程序部署到三个不同环境的情况(开发、测试和生产),并相应地定义三个 Profile 文件以有条件地加载某些 bean(dev、 12 | test、prod)。这时候,您决定添加一个预发布环境,您还希望在其中启用用 prod 配置文件标记的 bean。您会怎么做呢?有两个选择。一个是在预发布环境中激活 prod (这有点儿不太合理);另一个是更新源代码以添加一个 staging 文件,并将其分配给标记为 prod 的 bean(这打破了应用程序不变并可部署到任何环境,不需对源代码进行任何更改)。 13 | 14 | 相反,我建议使用 Profile 文件作为特性标志,与要创建的 bean 组关联以有条件地加载配置。考虑 Profile 文件提供哪些功能,并相应命名而不是考虑在哪里启用。然而,在某些情况下,一个 bean 确实需要处理特定平台上的基础设施。例如,您可能有一些 bean,仅当应用程序部署到 Kubernetes 时才应加载的(无论是预发布还是生产)。在这种情况下,可以定义 `kubernetes` profile。 15 | 16 | 在第 3 章中,您创建了 Catalog Service 应用程序来管理图书。本地运行时,应用中一本书都还没有,可以手工添加一些书籍以便使用应用程序。当然更好的方式是让应用程序在启动时自动生成一些测试数据,但只在需要时生成(例如,在开发或测试环境中)。是否加载测试数据可以建模为一个特性标志,然后就可以通过配置来启用/禁用这个功能。您可以定义 test-data profile 来触发测试数据的加载。这样,您就可以使用特性标志,使保存于配置文件中的测试数据独立于部署环境,而无需绑定于特定的部署基础设施。我们来实现这一点。 17 | 18 | 首先,在 Catalog Service 服务中添加一个新的 `com.polarbookshop.catalogservice.demo` 包,并创建 BookDataLoader 类。通过应用 `@profile` 注解,您可以指示 Spring 仅在 test-data profle 激活的情况下加载此类。然后,您可以使用第 3 章中实现的 BookRepository 来保存数据。最后,使用 `@EventListener(ApplicationReadyEvent.class)` 注解将触发测试数据在应用程序完成启动后生成。 19 | 20 | **清单 4.4 当 test-data profile 处于活动状态时加载测试数据(BookDataLoader.java)** 21 | ```java 22 | package com.polarbookshop.catalogservice.demo; 23 | 24 | import com.polarbookshop.catalogservice.domain.Book; 25 | import com.polarbookshop.catalogservice.domain.BookRepository; 26 | import org.springframework.boot.context.event.ApplicationReadyEvent; 27 | import org.springframework.context.annotation.Profile; 28 | import org.springframework.context.event.EventListener; 29 | import org.springframework.stereotype.Component; 30 | 31 | @Component 32 | @Profile("test-data") ❶ 33 | public class BookDataLoader { 34 | private final BookRepository bookRepository; 35 | 36 | public BookDataLoader(BookRepository bookRepository) { 37 | this.bookRepository = bookRepository; 38 | } 39 | 40 | @EventListener(ApplicationReadyEvent.class) ❷ 41 | public void loadBookTestData() { 42 | var book1 = new Book("1234567891", "Northern Lights", "Lyra Silvertongue", 9.90); 43 | var book2 = new Book("1234567892", "Polar Journey", "Iorek Polarson", 12.90); 44 | bookRepository.save(book1); 45 | bookRepository.save(book2); 46 | } 47 | } 48 | ``` 49 | 50 | ❶ 将类分配给“test-data” profile:仅当“test-data” profile 处于激活状态时才会注册类。 51 | 52 | ❷ 在发送 ApplicationReadyEvent 时触发测试数据生成,即应用程序启动完成时。 53 | 54 | 有几种方式可以设置哪个 profile 处于激活状态。在开发环境中,可以在 application.yml 文件中使用 spring.profiles.active 属性指定。 55 | 56 | ```yaml 57 | spring: 58 | profiles: 59 | active: test-data 60 | ``` 61 | 62 | 让我们验证一下设置是否有效。构建并运行应用程序(./gradlew bootRun)。首先,可以在应用程序日志中看到一条消息,列出所有激活的 profile(在本例中,它只能是 test-data,但可能还有其他的),如图 4.4 所示。 63 | 64 | ![](../../assets/4.4.jpg) 65 | **图 4.4 “test-data” profile 处于激活状态时 Catalog Service 的日志。** 66 | 67 | 然后,向应用程序发送请求以获取所有书籍。它应该返回清单 4.4 中创建的测试数据。 68 | 69 | ```bash 70 | $ http :9001/books 71 | ``` 72 | 73 | 验证完成后,使用 Ctrl+C 停止应用程序。 74 | 接下来,我将向您展示如何使用 profile 对配置数据进行分组。 75 | 76 | #### 将 Profiles 用作配置组 77 | 78 | Spring 框架允许您仅在给定的 profile 处于激活状态时才注册 bean。同样,Spring Boot 允许您定义只当特定 profile 处于激活状态时才加载配置数据。一种常见的方法是在配置文件的文件名称中增加 profile 名后缀。比如您可以创建一个新的 application-dev.yml 文件,并为 polar.greeting 定义一个新值,使 Spring 仅在 dev profile 处于活动状态时才加载。特定于 profile 的配置文件优先,于非特定 profile 的配置文件。因此 application-dev.yml 中定义的值优先于 application.yml 中的值。 79 | 80 | 在这种情况下,profile 用于对配置数据进行分组,并可以映射到部署环境中,而不会面临以前那些弊病。当然不要将特定于 profile 的配置文件与应用打包在一起。`15 因素` 法建议不要批量配置属性并将值分成以环境命名的组,然后与应用程序源代码打包在一起。原因是这样无法扩展:随着项目的发展,可能会为其创建新的环境。开发人员可以创建自己的定制环境配置来尝试新的功能。这样很快就会出现太多的配置组,而需要重新构建应用。相反,您应该让他们呆在应用程序外部。例如,在一个由 Config Server 提供服务的专用存储库中,您将在后续章节看到这一方式。 81 | 82 | 以下部分将介绍 Spring Boot 如何处理外部配置。教您如何使用命令行参数、JVM 系统属性和环境变量,在使用相同的构建产物时从外部获取配置数据。 -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/Introduction.md: -------------------------------------------------------------------------------- 1 | ## 4.1 Spring 中的配置:properties 和 profiles 2 | 3 | 术语 `配置(configuration)` 在不同的上下文中有不同的含义。当讨论 Spring 框架的核心功能及其 ApplicationContext 时,指的是哪些 bean(即在 Spring 中注册的 Java 对象)被定义为由 Spring 容器进行管理,并在需要时自动注入。例如,您有多种方式可以定义 Bean:在 XML 文件中(XML 配置)、在类上添加 @Configuration 注解(Java 配置),或通过注解 @Component(注解驱动配置)。 4 | 5 | 在本书中,除非另有说明,每当我提到配置时,我不是指以前的概念。而是指在不同部署之间可能会发生变化的一切,这是 `十五要素` 方法论所定义的。 6 | 7 | Spring 为您提供了一个方便的环境抽象,允许您访问任何配置数据,而不管其来源如何。Spring 应用程序环境的两个关键方法是 properties 和 profiles。您已经在上一章中使用了 properties。profiles 是一种只有在已启用给定 profile 时,才加载特定标记的一组 bean 或运行时配置数据的工具。图 4.2 显示了 Spring 应用程序的主要配置方法。 8 | 9 | ![](../../assets/4.2.jpg) 10 | 11 | **图 4.2 Environment 接口提供了对 Spring 应用程序的两个关键配置方法:properties 和 profiles。** 12 | 13 | 本节将介绍云原生的 properties 和 profiles,包括如何定义自定义 properties 以及何时使用 profiles。 -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.1-Configuring-an-application-through-command-line-arguments.md: -------------------------------------------------------------------------------- 1 | # 4.2.1 命令行参数配置应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.2-Configuring-an-application-through-JVM-system-properties.md: -------------------------------------------------------------------------------- 1 | # 4.2.2 JVM 系统属性配置应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.3-Configuring-an-application-through-environment-variables.md: -------------------------------------------------------------------------------- 1 | # 4.2.3 环境变量配置应用 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/Introduction.md: -------------------------------------------------------------------------------- 1 | # 4.2 外部化配置:一个构建多个配置 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.1-Using-Git-to-store-your-configuration-data.md: -------------------------------------------------------------------------------- 1 | # 4.3.1 使用 Git 存储配置数据 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.2-Setting-up-a-configuration-server.md: -------------------------------------------------------------------------------- 1 | # 4.3.2 设置 Config Server 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.3-Making-the-configuration-server-resilient.md: -------------------------------------------------------------------------------- 1 | # 4.3.3 使 Config Server 更有韧性 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.4-Understanding-the-configuration-server-REST-API.md: -------------------------------------------------------------------------------- 1 | # 4.3.4 理解 Config Server 的 Rest API 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.1-Setting-up-a-configuration-client.md: -------------------------------------------------------------------------------- 1 | # 4.4.1 设置 Config Client 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.2-Making-the-configuration-client-resilient.md: -------------------------------------------------------------------------------- 1 | # 4.4.2 使 Config Client 更有韧性 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.3-Refreshing-configuration-at-runtime.md: -------------------------------------------------------------------------------- 1 | # 4.4.3 运行时刷新配置 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/Introduction.md: -------------------------------------------------------------------------------- 1 | # 4.3 用 Spring Config Server 进行集中化配置管理 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/4.4-Using-a-configuration-server-with-Spring-Cloud-Config-Client/Introduction.md: -------------------------------------------------------------------------------- 1 | # 4.4 通过 Spring Cloud Config Client 使用配置服务 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/Introduction.md: -------------------------------------------------------------------------------- 1 | # 第 4 章 配置管理外部化 2 | 3 | 本章内容: 4 | 5 | * 使用 properties 和 profiles 配置 Spring 6 | * 使用 Spring Boot 应用外部配置 7 | * 使用 Spring Cloud Config Server 实现配置服务器 8 | * 使用 Spring Cloud Config Client 配置应用程序 9 | 10 | 在上一章中,您构建了一个用于管理图书目录的 RESTful 应用程序。作为实现的一部分,您定义了一些数据来配置应用程序的某些方面(在文件中)。例如,Tomcat 线程池或连接超时时间。下一步可能是将应用程序部署到不同的环境:首先是测试环境,然后是预发环境,最后是生产。如果您需要每个环境的都有不同的 Tomcat 配置,如何做到这一点呢? 11 | 12 | 传统的应用程序通常打包为一个应用包,包括源代码和一系列配置文件。包含不同环境的配置数据,并在运行时标记。这意味着您需要更新特定环境的配置数据时,都必须构建一个新的应用程序包。这一过程的一个改进是为每个环境创建不同的构建,但这意味着您无法保证在预发环境中运行的内容,在生产环境中也会以同样的方式运行,因为它们是不同的打包制品。 13 | 14 | `配置(Configuration)`定义为在部署之间可能发生更改的一切(根据 `十五要素` 方法论),如凭据、资源处理程序和支持服务的 URL。根据部署位置的不同,同一应用程序将有不同的需求,并且很可能需要不同的配置。云原生应用程序的一个关键特性是,应用程序制品将在整个环境中保持不变。无论将其部署到哪个环境,都不会更改应用程序制品。 15 | 16 | 您部署的每个版本都是构建和配置的组合。可以使用相同的构建部署到具有不同配置数据的不同环境,如图 4.1 所示。 17 | 18 | ![](../assets/4.1.jpg) 19 | **图 4.1 您部署的每个版本都是构建和配置的组合,每个环境都不同。** 20 | 21 | 可能需要跨部署进行更改的任何内容,都应该是可配置的。例如您可能希望更改凭据以访问支持服务、功能标志和数据库资源或外部 API 的 URL,所有这些都取决于您正在部署应用程序的环境。云原生应用程序支持配置外部化,因此您可以替换它,而无需重新生成代码。关于凭据,它甚至更重要,关键是不要将它们与应用程序代码一起存储。无数的数据泄露,都因为向公开的存储库提交了凭据信息。确保您不会是他们中的一员。 22 | 23 | 在 Spring 中,配置数据被抽象为 properties,以不同的方式定义键/值对,例如属性文件、JVM 系统属性和系统环境变量。本章介绍在云原生上下文中配置 Spring 应用程序的各个方面。我将介绍有关 Spring 如何处理配置的主要概念,包括 properties 和 profiles,以及如何使用 Spring Boot 应用外部化配置。然后,我将演示如何通过 Git 使用 Spring Cloud Config Server 设置配置服务存储库,作为存储配置数据的后端。最后,您将学习如何通过 Spring Cloud Config Client 访问 Config Server 来配置 Spring Boot 应用程序。 24 | 25 | 到本章结束时,您将能够根据您的需要和配置数据的类型,使用不同的方法来配置您的云原生 Spring 应用程序。表 4.1 总结了本章介绍的三种主要策略,以定义云原生应用程序的配置数据。第 13 章将进一步扩展本文涵盖的主题,包括机密管理以及如何在 Kubernetes 中使用 ConfigMaps 和 Secrets。 26 | 27 | >注意:本章示例的源代码可在 /Chapter04/04-begin 和 /Chapter04/04-end 文件中找到,包含最初和本章结束后的工程状态。([github.com/ThomasVitale/cloud-native-spring-in-action](https://github.com/ThomasVitale/cloud-native-spring-in-action)) 28 | 29 | **表 4.1 可以根据不同的策略配置云原生应用程序。根据配置数据类型和应用程序的要求,您可能会全部使用到它们。** 30 | 31 | 32 | | 配置策略 | 特征 | 33 | | :--- | :--- | 34 | | 随应用程序打包的属性文件 | · 可以作为应用程序支持的配置数据的规范。
· 用于定义合理的默认值,主要面向开发环境。 | 35 | | 环境变量 | · 任何操作系统都支持环境变量,因此非常方便。
· 大多数编程语言允许您访问环境变量。在 Java 中,可以使用 System.getenv() 方法来实现这一点。在 Spring 里依赖于 Environment 抽象类。
· 用于定义配置数据,具体取决于部署应用程序的基础架构/平台,例如活动配置文件、主机名、服务名和端口号。 | 36 | | 配置服务 | · 提供配置数据持久化、审核和计量。
· 允许使用加密或专用密钥管理机密库。
· 用于定义特定于应用程序的配置数据,例如连接池、凭据、功能标志、线程池和指向第三方服务的 URL。 | 37 | 38 | -------------------------------------------------------------------------------- /cn-translate/04-Externalized-configuration-management/Summary.md: -------------------------------------------------------------------------------- 1 | # 4.4 总结 2 | 3 | -------------------------------------------------------------------------------- /cn-translate/README.md: -------------------------------------------------------------------------------- 1 | # 云原生 Spring 实战 (MEAP) 2 | 3 | 《Cloud Native Spring in Action With Spring Boot and Kubernetes》 预计将于 2022 年夏出版。现在的翻译基于 Manning 出版社的 MEAP 版本。 4 | 5 | ![](assets/00-Vitale-CNS-MEAP-HI.png) 6 | 7 | 地址:https://www.manning.com/books/cloud-native-spring-in-action 8 | 9 | LiveBook: https://livebook.manning.com/book/cloud-native-spring-in-action 10 | 11 | ## 强烈推荐您购买此书 12 | ## 尊重作者,保护版权 13 | 14 | 15 | GitHub地址:[https://github.com/LeonLi0102/cloud-native-spring-in-action-translate.git](https://github.com/LeonLi0102/cloud-native-spring-in-action-translate.git) 16 | 17 | GitBook地址:[https://leonli0102.github.io/cloud-native-spring-in-action/](https://leonli0102.github.io/cloud-native-spring-in-action/) -------------------------------------------------------------------------------- /cn-translate/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [云原生 Spring 实战 (MEAP)](README.md) 4 | * [欢迎](welcome.md) 5 | * [第 1 章 云原生简介](01-Introduction-to-cloud-native/Introduction.md) 6 | * [1.1 什么是云原生](01-Introduction-to-cloud-native/1.1-What-is-cloud-native/Introduction.md) 7 | * [1.1.1 什么是云原生](01-Introduction-to-cloud-native/1.1-What-is-cloud-native/1.1.1-The-Three-Ps-of-Cloud-Native.md) 8 | * [1.2 云和云计算模型](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/Introduction.md) 9 | * [1.2.1 基础设施即服务](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.1-Infrastructure-as-a-Service.md) 10 | * [1.2.2 容器即服务](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.2-Container-as-a-Service.md) 11 | * [1.2.3 平台即服务](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.3-Platform-as-a-Service.md) 12 | * [1.2.4 功能即服务](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.4-Function-as-a-Service.md) 13 | * [1.2.5 软件即服务](01-Introduction-to-cloud-native/1.2-The-cloud-and-the-cloud-computing-model/1.2.5-Software-as-a-Service.md) 14 | * [1.3 云原生应用的特性](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/Introduction.md) 15 | * [1.3.1 可扩展性](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.1-Scalability.md) 16 | * [1.3.2 松耦合](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.2-Loose-coupling.md) 17 | * [1.3.3 强适应性](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.3-Resilience.md) 18 | * [1.3.4 可观测性](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.4-Observability.md) 19 | * [1.3.5 可管理性](01-Introduction-to-cloud-native/1.3-Properties-of-cloud-native-applications/1.3.5-Manageability.md) 20 | * [1.4 支持云原生的文化和实践](01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/Introduction.md) 21 | * [1.4.1 自动化](01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.1-Automation.md) 22 | * [1.4.2 持续交付](01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.2-Continuous-delivery.md) 23 | * [1.4.3 DevOps](01-Introduction-to-cloud-native/1.4-Culture-and-practices-supporting-cloud-native/1.4.3-DevOps.md) 24 | * [1.5 上云是最好的选择吗?](01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/Introduction.md) 25 | * [1.5.1 速度](01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.1-Speed.md) 26 | * [1.5.2 韧性](01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.2-Resilience.md) 27 | * [1.5.3 规模](01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.3-Scale.md) 28 | * [1.5.4 成本](01-Introduction-to-cloud-native/1.5-Is-the-cloud-your-best-option/1.5.4-Cost.md) 29 | * [1.6 云原生拓扑](01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/Introduction.md) 30 | * [1.6.1 容器](01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.1-Containers.md) 31 | * [1.6.2 编排](01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.2-Orchestration.md) 32 | * [1.6.3 无服务器架构](01-Introduction-to-cloud-native/1.6-Cloud-native-topologies/1.6.3-Serverless.md) 33 | * [1.7 云原生应用架构](01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/Introduction.md) 34 | * [1.7.1 从分层到微服务到更高级别](01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/1.7.1-From-multi-tiered-to-microservice-architectures-and-beyond.md) 35 | * [1.7.2 基于服务的云原生应用体系结构](01-Introduction-to-cloud-native/1.7-Architectures-for-cloud-native-applications/1.7.2-Service-based-architecture-for-cloud-native-applications.md) 36 | * [1.8 总结](01-Introduction-to-cloud-native/Summary.md) 37 | * [第 2 章 云原生模式和技术](02-Cloud-native-patterns-and-technologies/Introduction.md) 38 | * [2.1 云原生开发原则:十二要素及其他](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/Introduction.md) 39 | * [2.1.1 一份基准代码对应一个应用](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.1-One-codebase-one-application.md) 40 | * [2.1.2 API 优先](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.2-API-first.md) 41 | * [2.1.3 依赖管理](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.3-Dependency-management.md) 42 | * [2.1.4 设计、构建、发布、运行](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.4-Design-build-release-run.md) 43 | * [2.1.5 配置、证书、代码](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.5-Configuration-credentials-and-code.md) 44 | * [2.1.6 日志](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.6-Logs.md) 45 | * [2.1.7 可丢弃](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.7-Disposability.md) 46 | * [2.1.8 后端服务](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.8-Backing-services.md) 47 | * [2.1.9 环境一致性](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.9-Environment-parity.md) 48 | * [2.1.10 管理员进程](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.10-Administrative-processes.md) 49 | * [2.1.11 端口绑定](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.11-Port-binding.md) 50 | * [2.1.12 无状态进程](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.12-Stateless-processes.md) 51 | * [2.1.13 并发](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.13-Concurrency.md) 52 | * [2.1.14 遥测](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.14-Telemetry.md) 53 | * [2.1.15 认证和授权](02-Cloud-native-patterns-and-technologies/2.1-Cloud-native-development-principles-Twelve-Factors-and-beyond/2.1.15-Authentication-and-authorization.md) 54 | * [2.2 使用 Spring 构建云原生应用](02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/Introduction.md) 55 | * [2.2.1 Spring 全景概览](02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/2.2.1-Overview-of-the-Spring-landscape.md) 56 | * [2.2.2 创建 Spring Boot 应用](02-Cloud-native-patterns-and-technologies/2.2-Building-cloud-native-applications-with-Spring/2.2.2-Building-a-Spring-Boot-application.md) 57 | * [2.3 使用 Docker 容器化应用](02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/Introduction.md) 58 | * [2.3.1 Docker 介绍:镜像和容器](02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/2.3.1-Introducing-Docker-Images-and-containers.md) 59 | * [2.3.2 运行 Spring 应用容器](02-Cloud-native-patterns-and-technologies/2.3-Containerizing-applications-with-Docker/2.3.2-Running-a-Spring-application-as-a-container.md) 60 | * [2.4 使用 Kubernetes 管理容器](02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/Introduction.md) 61 | * [2.4.1 介绍 Kubernetes 的 Deployment、Pod 和 Service](02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/2.4.1-Introducing-Kubernetes-Deployments-pods-and-services.md) 62 | * [2.4.2 在 Kubernetes 是运行 Spring 应用](02-Cloud-native-patterns-and-technologies/2.4-Managing-containers-with-Kubernetes/2.4.2-Running-a-Spring-application-on-Kubernetes.md) 63 | * [2.5 云原生应用 —— 极地书店](02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/Introduction.md) 64 | * [2.5.1 理解系统需求](02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/2.5.1-Understanding-the-requirements-of-the-system.md) 65 | * [2.5.2 工程中用到的技术和模式](02-Cloud-native-patterns-and-technologies/2.5-Polar-Bookshop-A-cloud-native-application/2.5.2-Exploring-patterns-and-technologies-used-in-the-project.md) 66 | * [2.6 总结](02-Cloud-native-patterns-and-technologies/Summary.md) 67 | * [第 3 章 进行云原生应用开发](03-Getting-started-with-cloud-native-development/Introduction.md) 68 | * [3.1 创建云原生项目](03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/Introduction.md) 69 | * [3.1.1 一份基准代码对应一个应用](03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/3.1.1-One-codebase-one-application.md) 70 | * [3.1.2 使用 Maven 或 Gradel 管理依赖](03-Getting-started-with-cloud-native-development/3.1-Bootstrapping-a-cloud-native-project/3.1.2-Dependency-management-with-Gradle-and-Maven.md) 71 | * [3.2 使用内嵌服务器](03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/Introduction.md) 72 | * [3.2.1 可执行 JAR 和内嵌服务:为云做好准备](03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.1-Executable-JARs-and-embedded-servers-Ready-for-the-cloud.md) 73 | * [3.2.2 理解 一个请求一个线程 模式](03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.2-Understanding-the-thread-per-request-model.md) 74 | * [3.2.3 配置内嵌 Tomcat](03-Getting-started-with-cloud-native-development/3.2-Working-with-embedded-servers/3.2.3-Configuring-the-embedded-Tomcat.md) 75 | * [3.3 使用 Spring MVC 构建 RESTful 应用](03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/Introduction.md) 76 | * [3.3.1 REST API 第一,业务逻辑第二](03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.1-REST-API-first-business-logic-later.md) 77 | * [3.3.2 使用 Spring MVC 实现 REST API](03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.2-Implementing-a-REST-API-with-Spring-MVC.md) 78 | * [3.3.3 数据校验和出错处理](03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.3-Data-validation-and-error-handling.md) 79 | * [3.3.4 为未来需求扩展 API](03-Getting-started-with-cloud-native-development/3.3-Building-a-RESTful-application-with-Spring-MVC/3.3.4-Evolving-APIs-for-future-requirements.md) 80 | * [3.4 使用 Spring 测试 RESTful 应用](03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/Introduction.md) 81 | * [3.4.1 使用 JUnit 5 进行单元测试](03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.1-Unit-tests-with-JUnit-5.md) 82 | * [3.4.2 使用 @SpringBootTest 进行集成测试](03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.2-Integration-tests-with-SpringBootTest.md) 83 | * [3.4.3 使用 @WebMvcTest 测试 REST 控制器](03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.3-Testing-REST-controllers-with-WebMvcTest.md) 84 | * [3.4.4 使用 @JsonTest 测试 JSON 序列化](03-Getting-started-with-cloud-native-development/3.4-Testing-a-RESTful-application-with-Spring/3.4.4-Testing-the-JSON-serialization-with-JsonTest.md) 85 | * [3.5 使用 GitHub Action 进行持续集成](03-Getting-started-with-cloud-native-development/3.5-Continuous-integration-pipelines-with-GitHub-Actions/Introduction.md) 86 | * [3.5.1 使用 GitHub Action 进行自动构建和测试](03-Getting-started-with-cloud-native-development/3.5-Continuous-integration-pipelines-with-GitHub-Actions/3.5.1-GitHub-Actions-Automating-builds-and-tests.md) 87 | * [3.6 总结](03-Getting-started-with-cloud-native-development/Summary.md) 88 | * [第 4 章 配置管理外部化](04-Externalized-configuration-management/Introduction.md) 89 | * [4.1 Spring 中的配置:properties 和 profiles](04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/Introduction.md) 90 | * [4.1.1 Properties:键值对](04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/4.1.1-Properties-Key-value-pairs-for-configuration.md) 91 | * [4.1.2 Profiles:特性标志和配置分组](04-Externalized-configuration-management/4.1-Configuration-in-Spring-properties-and-profiles/4.1.2-Profiles-Feature-flags-and-configuration-groups.md) 92 | * [4.2 外部化配置:一个构建多个配置](04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/Introduction.md) 93 | * [4.2.1 命令行参数配置应用](04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.1-Configuring-an-application-through-command-line-arguments.md) 94 | * [4.2.2 JVM 系统属性配置应用](04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.2-Configuring-an-application-through-JVM-system-properties.md) 95 | * [4.2.3 环境变量配置应用](04-Externalized-configuration-management/4.2-Externalized-configuration-one-build-multiple-configurations/4.2.3-Configuring-an-application-through-environment-variables.md) 96 | * [4.3 用 Spring Config Server 进行集中化配置管理](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/Introduction.md) 97 | * [4.3.1 使用 Git 存储配置数据](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.1-Using-Git-to-store-your-configuration-data.md) 98 | * [4.3.2 设置 Config Server](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.2-Setting-up-a-configuration-server.md) 99 | * [4.3.3 使 Config Server 更有韧性](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.3-Making-the-configuration-server-resilient.md) 100 | * [4.3.4 理解 Config Server 的 Rest API](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.3.4-Understanding-the-configuration-server-REST-API.md) 101 | * [4.4 通过 Spring Cloud Config Client 使用配置服务](04-Externalized-configuration-management/4.4-Using-a-configuration-server-with-Spring-Cloud-Config-Client/Introduction.md) 102 | * [4.4.1 设置 Config Client](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.1-Setting-up-a-configuration-client.md) 103 | * [4.4.2 使 Config Client 更有韧性](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.2-Making-the-configuration-client-resilient.md) 104 | * [4.4.3 运行时刷新配置](04-Externalized-configuration-management/4.3-Centralized-configuration-management-with-Spring-Cloud-Config-Server/4.4.3-Refreshing-configuration-at-runtime.md) 105 | * [4.4 总结](04-Externalized-configuration-management/Summary.md) 106 | 107 | -------------------------------------------------------------------------------- /cn-translate/assets/00-Vitale-CNS-MEAP-HI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/00-Vitale-CNS-MEAP-HI.png -------------------------------------------------------------------------------- /cn-translate/assets/1.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.1.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.10.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.11.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.12.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.13.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.14.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.2.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.3.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.4.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.5.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.6.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.7.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.8.jpg -------------------------------------------------------------------------------- /cn-translate/assets/1.9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/1.9.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.1.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.10.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.11.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.12.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.13.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.14.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.15.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.2.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.3.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.4.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.5.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.6.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.7.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.8.jpg -------------------------------------------------------------------------------- /cn-translate/assets/2.9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/2.9.jpg -------------------------------------------------------------------------------- /cn-translate/assets/4.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/4.1.jpg -------------------------------------------------------------------------------- /cn-translate/assets/4.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/4.2.jpg -------------------------------------------------------------------------------- /cn-translate/assets/4.3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/4.3.jpg -------------------------------------------------------------------------------- /cn-translate/assets/4.4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonLi0102/cloud-native-spring-in-action-translate/fc7b024252f748ebc6241ce25638171265c8afb3/cn-translate/assets/4.4.jpg -------------------------------------------------------------------------------- /cn-translate/book.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cloud Native Spring In Action", 3 | "author": "Craig Walls", 4 | "language" : "zh-hans", 5 | "plugins": [ 6 | "-search", 7 | "search-pro", 8 | "back-to-top-button", 9 | "chapter-fold", 10 | "code", 11 | "copy-code-button", 12 | "pageview-count", 13 | "auto-scroll-table", 14 | "popup", 15 | "theme-comscore", 16 | "prism", 17 | "-highlight", 18 | "fontsettings" 19 | 20 | ], 21 | "pluginsConfig": { 22 | "fontSettings": { 23 | "theme": "white", 24 | "family": "serif", 25 | "size": 4 26 | }, 27 | "github": { 28 | "url": "https://github.com/LeonLi0102/cloud-native-spring-in-action-translate.git" 29 | }, 30 | "prism": { 31 | "css": [ 32 | "prismjs/themes/prism-tomorrow.css" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cn-translate/welcome.md: -------------------------------------------------------------------------------- 1 | # 欢迎 2 | 3 | 感谢您购买 MEAP 版的《Cloud Native Spring In Action》。 4 | 5 | 为了从本书中获得最大的收益,您需要熟练掌握 Java 编程,需要具有构建 web 应用程序的经验,还要有 Spring 核心功能的基本知识。我假设您也熟悉 Git、面向对象编程、分布式系统、数据库和测试等。 6 | 7 | 在过去的几年中,越来越明显的是,许多组织不得不选择上云来保持经营活动。基于应用服务器和“雪花”(参考 [SnowflakeServer](https://martinfowler.com/bliki/SnowflakeServer.html))式内部传统基础架构,很难满足现代应用程序的需求:可扩展性、弹性、零停机时间、可靠性、短反馈周期和频繁发布。为了充分利用云的功能,只将传统应用程序迁移到新的基础架构是不够的,还需要一些别的东西。应用程序必须成为云原生应用程序。 8 | 9 | 本书将带领您在云原生世界中展开一段激动人心的旅程。从开发环境到生产环境,使用 Spring、Docker 和 Kubernetes 的最新功能。您将有机会实现每一个新想法,逐步为在线书店构建一个完整的云原生系统。到本书结束,您将把它部署到公有云的 Kubernetes 集群中。 10 | 11 | 本书分为四个部分。第 1 部分将引导您了解云原生环境,定义成为云原生应用程序需要些什么,并建立一些工具、技术和模式,以备后续使用。 12 | 13 | 第 2 部分将让您了解云原生开发的基础知识。您将了解 与 Spring RESTful 服务和数据持久化。了解如何跨环境管理配置,定义自动化持续集成过程,了解 Docker 容器化如何工作。最后将您的应用部署到本地 Kubernetes 集群。 14 | 15 | 在第 3 部分中,您的旅程将达到一个全新的高度。您将单体应用迁移到云上的分布式系统中。您将了解响应式编程、可扩展性、弹性和边缘服务。然后,您将探索事件驱动体系结构,并通过身份验证、授权和加密保护您的系统。 16 | 17 | 第 4 部分中,您将确保应用程序的可观测性,处理日志记录、跟踪和监视。最后,您将到达渴望已久的目的地:生产环境。您将学习如何将应用程序部署到 Kubernetes 公有云集群,并实现自动化交付和部署。在生产环境的新旅程开始了。您将熟悉云原生冒险中的下一步,学习迁移现有应用程序。 18 | 19 | 请让我知道您对目前为止所写的这些内容的想法,以及您希望在接下来的章节中看到哪些内容?欢迎您在 [liveBook 讨论论坛](https://livebook.manning.com/#!/book/cloud-native-spring-in-action/discussion) 上发表意见 —— 您的反馈对改进《Cloud Native Spring In Action》一书有重要价值。 20 | 21 | 您可以在 [GitHub](https://github.com/ThomasVitale/cloud-native-spring-in-action) 附带的存储库中找到本书中使用的所有代码示例。 22 | 23 | 再次感谢您的关注和购买! 24 | 25 | —Thomas Vitale 26 | 27 | --------------------------------------------------------------------------------