欢迎来到我们学习 Go 语言的云原生编程之旅的最后一章。到目前为止,您应该具备足够的知识来构建生产级微服务、设计复杂的分布式架构、利用关键 Amazon web 服务的强大功能、使用容器来增强软件的能力等等。
然而,云本地编程的主题是一个非常深刻和庞大的主题。这意味着你仍然可以学习一些主题来丰富你在该领域的知识和技能。本章的目的是为您指明一条道路,从本书结束的地方开始,提供一些本书中未涉及的主题的实用概述,这些主题是您在吸收本书中包含的知识后可以寻求的有力途径。
在本章中,我们将介绍以下主题:
- 附加的微服务通信模式和协议,如协议缓冲区和 GRPC
- 云提供商提供的更有用的功能
- 其他云提供商(Azure、GCP 和 OpenStack)
- 无服务器计算
在本书中,我们介绍了两种微服务相互通信的方法:
- 第一种方法是通过 RESTful API,其中 web HTTP 层将构建到微服务中,有效地允许微服务与任何 web 客户端通信,无论该 web 客户端是另一个微服务还是 web 浏览器。这种方法的一个优点是,它使微服务能够在需要时与外部世界通信,因为 HTTP 现在是一种通用协议,所有软件堆栈都支持它。然而,这种方法的缺点是,HTTP 可能是一种具有多层的重型协议,当需要内部微服务之间快速高效的通信时,这可能不是最佳选择。
- 第二种方法是通过消息队列,其中消息代理软件(如 RabbitMQ 或 Kafka)将促进微服务之间的消息交换。消息代理接收来自发送微服务的消息,对消息进行排队,然后将消息传递给先前表示对这些消息感兴趣的微服务。这种方法的一个主要优点是,它可以巩固大规模分布式微服务架构中的数据一致性,如第 11 章、迁移所述。这种方法支持事件驱动的分布式架构,如事件源和 CQR。然而,如果我们的扩展需求在范围上相对简单,那么这种方法对于我们的需求来说可能太复杂了。这是因为它要求我们维护一个 MessageBroker 软件及其所有配置和后端。在这些情况下,直接的微服务到微服务的通信可能就是我们所需要的。
如果您还没有注意到,这两种方法都有一个明显的缺点,那就是它们不能提供直接有效的微服务到微服务的通信。我们可以采用两种流行的技术进行直接微服务通信:协议缓冲区和 GRPC。
在他们的官方文档中,协议缓冲区被定义为一种与语言无关、与平台无关的机制,用于序列化结构化数据。让我们看一个例子来帮助清楚地了解协议缓冲区是什么。
假设您的应用中有两个微服务;第一个微服务(服务 1)已收集新客户的信息,并希望将其发送给第二个微服务(服务 2)。此数据被视为结构化数据,因为它包含结构化信息,如客户姓名、年龄、职务和电话号码。发送此数据的一种方法是通过 HTTP 将其作为 JSON 文档(我们的数据格式)从服务 1 发送到服务 2。但是,如果我们希望以更小的形式更快地发送这些数据,该怎么办?这就是协议缓冲区出现的地方。在 Service1 内部,协议缓冲区将获取 customer 对象,然后将其序列化为紧凑形式。从那里,我们可以获取这段经过编码的压缩数据,并通过高效的通信协议(如 TCP 或 UDP)将其发送到服务 2。
请注意,在前面的示例中,我们将协议缓冲区描述为服务内部。这是正确的,因为协议缓冲区作为软件库提供,我们可以导入并包含在代码中。有广泛的编程语言(GO,爪哇,C,C++,露比,Python,更多)的协议缓冲包。
协议缓冲区的工作方式如下:
- 您在一个特殊文件中定义数据,称为
proto
文件。 - 您可以使用一种称为协议缓冲区编译器的软件将 proto 文件编译成用您选择的编程语言编写的代码文件。
- 您可以使用生成的代码文件和所选语言的协议缓冲区软件包来构建软件。
简而言之,这就是协议缓冲区。为了更深入地了解协议缓冲区,请转至https://developers.google.com/protocol-buffers/ ,在这里您可以找到好的文档,帮助您开始使用该技术。
目前有两种常用的协议缓冲区版本:协议缓冲区 2 和协议缓冲区 3。目前在线提供的许多培训资源包括最新版本 Protocol Buffers 3。如果您正在寻找有关协议缓冲区版本 2 的帮助资源,您可以在我的网站上查看本文 http://www.minaandrawos.com/2014/05/27/practical-guide-protocol-buffers-protobuf-go-golang/ 。
协议缓冲区技术缺少的一个关键特性是通信部分。协议缓冲区擅长将数据编码和序列化为紧凑的形式,我们可以与其他微服务共享。然而,当最初构思协议缓冲区的概念时,只考虑了序列化,而没有考虑将数据实际发送到其他地方的部分。为此,开发人员习惯于卷起袖子,实现自己的 TCP 或 UDP 应用层,以便在服务之间交换编码数据。然而,如果我们不能抽出时间和精力来担心一个高效的通信层呢?这就是 GRPC 进入画面的地方。
GRPC 可以简单地描述为协议缓冲区与顶部的 RPC 层相结合。远程过程调用(RPC层)是一个软件层,它允许不同的软件(如微服务)通过有效的通信协议(如 TCP)进行交互。使用 GRPC,您的微服务可以通过协议缓冲区版本 3 序列化结构化数据,然后将能够与其他微服务通信此数据,而无需担心实现通信层
如果应用架构需要在微服务之间进行高效快速的交互,同时不能使用消息队列或 Web API,那么为下一个应用考虑 GRPC。
要开始使用 GRPC,请访问https://grpc.io/ 。与协议缓冲区类似,GRPC 由多种编程语言支持。
在这本书中,我们专门用两章介绍 AWS 基础知识的实践,重点介绍如何编写 Go 微服务,使其能够舒适地位于亚马逊的云上。然而,AWS 是一个非常深刻的主题,值得一整本书来涵盖,而不是仅仅几章。在本节中,我们将简要概述一些有用的 AWS 技术,这些技术在本书中没有介绍。您可以使用以下部分作为学习 AWS 后续步骤的介绍。
在第 8 章、AWS II-S3、SQS、API 网关和 DynamoDB 中我们介绍了流行的 AWS DynamoDB 服务。我们学习了什么是 DynamoDB,它如何建模数据,以及如何编写能够利用 DynamoDB 能力的 Go 应用
DynamoDB 有一个强大的特性,我们在本书中没有机会介绍,这就是 DynamoDB 流。DynamoDB 流允许我们在 DynamoDB 表中的项发生更改的同时捕获更改。实际上,这意味着我们可以对数据库中发生的数据更改做出实时反应。像往常一样,让我们举一个例子来巩固这个意思。
假设我们正在构建支持大型多人游戏的云本地分布式微服务应用。假设我们使用 DynamoDB 作为应用的数据库后端,我们的一个微服务向数据库添加了一个新播放器。如果我们在应用中使用 DynamoDB 流,那么其他感兴趣的微服务将能够在添加新玩家信息后不久捕获新玩家信息。这允许其他微服务使用此新信息进行相应操作。例如,如果另一个微服务负责在游戏地图中定位玩家,那么它会将新玩家附加到游戏地图上的开始位置。
DynamoDB 流的工作方式很简单。它们按顺序捕获 DynamoDB 表项发生的更改。信息存储在长达 24 小时的日志中。我们编写的其他应用可以访问此日志并捕获数据更改
换句话说,如果项目被创建、删除或更新,DynamoDB streams 将存储项目主键和发生的数据修改
需要在需要监视的表上启用 DynamoDB 流。我们还可以在现有表上禁用 DynamoDB 流,如果出于任何原因,这些表不需要更多的监视。DynamoDB 流与 DynamoDB 表并行运行,这基本上意味着使用它们不会影响性能。
要开始使用 DynamoDB streams,请查看http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html
要开始使用 Go 编程语言中的 DynamoDB streams 支持,请查看https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodbstreams/ 。
由于 AWS 的设计初衷是用于大规模分布式微服务应用,因此 AWS 具有内置功能,允许这些大型应用的开发人员在云中以尽可能少的手动干预自动缩放其应用
在 AWS 世界中,“自动缩放”一词主要指三件事:
- 能够自动替换不健康的应用或坏的 EC2 实例,而无需您的干预。
- 能够自动创建新的 EC2 实例来处理 microservices 应用上增加的负载,而无需您的干预。然后,在应用负载减少时关闭 EC2 实例的能力。
- 当应用负载增加时,能够自动增加应用可用的云服务资源。AWS 云资源不仅仅限于 EC2。DynamoDB 读写吞吐量就是一个云服务资源的例子,它可以根据您的需要自动上升或下降。
为满足自动校准的广泛定义,AWS 自动校准服务提供了三个主要功能:
- EC2 实例的车队管理:此功能允许您监控运行中 EC2 实例的运行状况,自动替换坏实例而无需手动干预,并在配置多个区域时跨多个区域平衡 EC2 实例。
- 动态缩放:此功能允许您首先配置跟踪策略,以适应应用的负载量。例如,监视 CPU 利用率或捕获传入请求的数量。然后,动态缩放功能可以根据配置的目标限制自动添加或删除 EC2 实例
- 应用自动扩展:此功能允许您根据应用的需要动态扩展超出 EC2 的 AWS 服务上的资源
要开始使用 AWS 自动校准服务,请访问https://aws.amazon.com/autoscaling/ 。
在第 8 章、AWS II-S3、SQS、API 网关和 DynamoDB中,当我们在 AWS 世界中介绍数据库服务时,我们专门介绍了 DynamoDB。DynamoDB 是亚马逊在 AWS 上提供的一种托管 NoSQL 数据库服务。如果您在数据库引擎方面有足够的技术专长,您可能会问一个显而易见的问题:关系数据库呢?难道不应该有一个管理的 AWS 服务吗?
前两个问题的答案是有,有,叫做亚马逊关系数据库服务(RDS。AWS RDS 允许开发人员在云上轻松配置、操作、扩展和部署关系数据库引擎
AmazonRDS 支持许多开发人员使用和喜爱的一系列著名的关系数据库引擎。这包括 PostgreSQL、MySQL、MariaDB、Oracle 和 Microsoft SQL server。除了 RDS 之外,Amazon 还提供了一种称为数据库迁移服务的服务,允许您轻松地将现有数据库迁移或复制到 Amazon RDS。
要开始使用 AWS RDS,请访问https://aws.amazon.com/rds/ 。要构建能够与 RDS 交互的 Go 应用,请访问https://docs.aws.amazon.com/sdk-for-go/api/service/rds/ 。
到目前为止,我们一直将 AWS 作为云提供商。当然,还有其他提供类似服务的提供商,其中最大的两家是微软 Azure 云和谷歌云平台。除此之外,还有许多其他提供商也提供 IaaS 解决方案,通常都是基于开源平台 OpenStack。
所有云提供商都采用类似的概念,因此,如果您有使用其中一个概念的经验,您可能会找到绕过其他概念的方法。出于这个原因,我们决定不在本书中深入讨论每一个问题,而是将重点放在 AWS 上,并向您简要介绍其他提供商及其不同之处。
您可以在上注册 Azure 云 https://azure.microsoft.com/en-us/free/ 。与 AWS 一样,Azure 提供了多个区域和可用性区域,您可以在其中运行服务。此外,大多数 Azure 核心服务的工作方式与 AWS 类似,尽管它们的名称通常不同:
- 管理虚拟机的服务(AWS 术语中的 EC2)被称为虚拟机。创建虚拟机时,您需要选择一个映像(Linux 和 Windows 映像都受支持)、提供 SSH 公钥并选择机器大小。其他核心概念的名称也类似。您可以使用网络安全组配置网络访问规则,使用Azure 负载平衡器(AWS 中称为弹性负载平衡器)配置负载平衡流量,并使用VM 规模集管理自动缩放。
- 关系数据库(由 AWS 中的关系数据库服务管理)由Azure SQL 数据库管理。但是,在编写本书时,仅支持 Microsoft SQL 数据库。对 MySQL 和 PostgreSQL 数据库的支持仅作为预览服务提供。
- NoSQL 数据库类似于 DynamoDB,以Azure 宇宙数据库的形式提供。
- 类似于简单队列服务的消息队列由队列存储服务提供。
- 使用应用网关可以访问您的服务提供的 API。
要从您的 Go 应用中使用 Azure 服务,您可以使用Azure SDK for Go,该 SDK 可在上获得 https://github.com/Azure/azure-sdk-for-go 。您可以使用通常的go get
命令安装:
$ go get -u github.com/Azure/azure-sdk-for-go/...
Azure SDK for Go 目前仍在大力开发中,应谨慎使用。为避免对 SDK 中的任何突破性更改感到惊讶,请确保您使用依赖关系管理工具,如Glide将此库的一个版本放入您的供应商/目录中(如您在第 9 章、持续交付中所了解的)。
谷歌云平台(GCP是谷歌提供的 IaaS 产品。您可以在注册 https://console.cloud.google.com/freetrial 。与 Azure 云一样,您可以识别许多核心功能,尽管名称不同:
- 您可以使用谷歌计算引擎管理虚拟实例。通常,每个实例都是从映像、选定的机器类型和 SSH 公钥创建的。您没有安全组,而是有防火墙规则,自动缩放组称为托管实例组。
- 关系数据库由云 SQL服务提供。GCP 同时支持 MySQL 和 PostgreSQL 实例。
- 对于 NoSQL 数据库,您可以使用云数据存储服务。
- 云发布/订阅服务提供了实现复杂发布/订阅架构的可能性(事实上,用 SQS 取代了 AWS 提供的可能性)。
由于两者都来自谷歌,不用说 GCP 和 Go 齐头并进(双关语)。您可以通过通常的go get
命令安装 Go SDK:
$ go get -u cloud.google.com/go
还有许多云提供商在开源云管理软件 OpenStack(上构建产品 https://www.openstack.org )。OpenStack 是一个高度模块化的软件,基于它构建的云在其设置中可能会有很大的差异,因此很难对它们做出任何普遍有效的声明。典型的 OpenStack 安装可能包括以下服务:
- Nova管理虚拟机实例,中子管理网络。在管理控制台中,您将在实例和网络标签下找到它。
- 尊和库里尔管理集装箱。由于这些组件相对较年轻,因此在 OpenStack 云中发现托管 Kubernetes 集群可能更常见。
- Trove为关系数据库和非关系数据库提供数据库服务,如 MySQL 或 MongoDB。
- Zaqar提供类似 SQS 的消息传递服务。
如果您想从 Go 应用访问 OpenStack 功能,可以选择多个库。首先,有一个官方的客户端库——github.com/openstack/golang-client——但目前还不推荐用于生产。在撰写本书时,OpenStack 最成熟的 Go 客户端库是github.com/gophercloud/gophercloud库。
在第 6 章在容器中部署应用中,我们深入了解了如何使用现代容器技术部署 Go 应用。在将这些容器部署到云环境中时,您有多种不同的方法。
部署容器化应用的一种可能性是使用编排引擎,如Kubernetes。这在使用 Microsoft Azure 云或 Google 云平台时尤其容易。这两个提供商都将 Kubernetes 作为托管服务提供,尽管不是以该名称提供;查找Azure 容器服务(AKS)或谷歌容器引擎(GKE)。
虽然 AWS 不提供托管 Kubernetes 服务,但它们也提供类似的服务,称为EC2 容器服务(ECS。由于 ECS 是 AWS 上唯一可用的服务,因此它与其他 AWS 核心服务紧密集成,这既有优势也有劣势。当然,您可以使用以 VM、网络和存储形式提供的构建块在 AWS 上建立自己的 Kubernetes 集群。做这件事非常复杂,但不要绝望。您可以使用第三方工具在 AWS 上自动设置 Kubernetes 群集。其中一个工具是kops。
您可以在下载 kopshttps://github.com/kubernetes/kops 。之后,按照项目文档中的 AWS 设置说明进行操作 https://github.com/kubernetes/kops/blob/master/docs/aws.md 。
Kops 本身也是用 Go 编写的,它使用的 AWS SDK 与您在第 7 章、AWS I–基础、AWS SDK for Go 和 EC2以及第 8 章、AWS II-S3、SQS、API 网关和 DynamoDB中所遇到的非常相同。看一下源代码,看看 AWS 客户机库的一些非常复杂的用法的真实示例。
在使用传统的基础架构即服务产品时,系统会为您提供大量虚拟机以及相应的基础架构(如存储和网络)。您通常需要自己操作这些虚拟机中运行的所有东西。这通常意味着不仅要编译应用,还要整个操作系统,包括成熟的 Linux(或 Windows)系统的每个系统服务的内核。您还负责基础架构的容量规划(这意味着估计应用的资源需求并为自动缩放组定义合理的边界)。
所有这些都意味着运营开销会让你远离实际工作,也就是说,构建和部署驱动你业务的软件。为了减少这种开销,您可以使用平台即服务产品而不是 IaaS 产品。PaaS 托管的一种常见形式是使用容器技术,开发人员只需提供一个容器映像,而提供者负责运行(以及可选地扩展)应用和管理底层基础设施。典型的基于容器的 PaaS 产品包括 AWS 的 EC2 容器服务或任何 Kubernetes 集群,如 Azure 容器服务或 Google 容器引擎。基于非容器的 PaaS 产品可能包括 AWS Elastic Beanstalk 或 Google 应用引擎。
最近,出现了另一种方法,努力消除比 PaaS 产品更多的操作开销:无服务器计算。当然,这个名字有很大的误导性,因为在无服务器架构上运行的应用显然仍然需要服务器。关键的区别在于,这些服务器的存在对开发人员是完全隐藏的。开发人员只提供要执行的应用,而提供程序负责为此应用提供基础设施,并部署和运行它。这种方法适用于微服务架构,因为部署使用 web 服务、消息队列或其他方式相互通信的小块代码变得非常容易。极端情况下,这通常会导致将单个功能部署为服务,从而产生无服务器计算的替代术语:功能即服务(FaaS。
许多云提供商提供 FaaS 功能作为其服务的一部分,最突出的例子是AWS Lambda。在编写本书时,AWS Lambda 还没有正式支持 Go 作为编程语言(支持的语言有 JavaScript、Python、Java 和 C#),并且运行 Go 函数只能使用第三方包装器,如https://github.com/eawsy/aws-lambda-go 。
其他云提供商也提供类似的服务。Azure 提供Azure 函数(支持 JavaScript、C#、F#、PHP、Bash、Batch 和 PowerShell),GCP 提供云函数作为测试版产品(仅支持 JavaScript)。如果您正在运行 Kubernetes 群集,则可以使用裂变框架(https://github.com/fission/fission )运行自己的 FaaS 平台(甚至支持 Go)。然而,裂变是处于早期阿尔法发展阶段的一种产品,尚未推荐用于生产。
正如您可能已经注意到的,对 Go 语言的支持在流行的 FaaS 产品中还没有普及。然而,考虑到 Go 作为编程语言和无服务器架构的流行,并不是所有的希望都破灭了。
有了这些,我们就到了书的结尾。到目前为止,您应该有足够的知识来构建具有弹性、分布式和可扩展性的复杂微服务云本机应用。通过本章,您还应该了解下一步的方向,将新学到的知识提升到下一个层次。我们感谢您给我们这个机会指导您完成这一学习旅程,并期待成为您未来旅程的一部分