元数据

微服务实战

  •  微服务实战|200
  • 书名: 微服务实战
  • 作者: 摩根·布鲁斯 保罗·A.佩雷拉
  • 简介: 《微服务实战》主要介绍如何开发和维护基于微服务的应用。本书源自作者从日常开发中得到的积累和感悟,其中给出的案例覆盖从微服务设计到部署的各个阶段,能够带给你真实的沉浸式体验。通过阅读本书,你不仅能够了解用微服务搭建高效的持续交付流水线的方法,还能够运用Kubernetes、Docker以及GoogleContainerEngine进一步探索书中的示例。
  • 出版时间 2020-05-01 00:00:00
  • ISBN: 9787115529879
  • 分类: 计算机-计算机综合
  • 出版社: 人民邮电出版社

高亮划线

1.3 微服务开发生命周期

  • 📌 开发者需要通过在出现错误的时候进行回退、对于一些不友好的调用方要限制其请求速率、动态寻找健康服务等方式来使服务具有防御性。 ^31151874-18-3317-3378
    • ⏱ 2021-12-23 22:53:51

2.3 开发新功能

  • 📌 将那些因为相同原因而修改的内容聚合到一起 ^31151874-24-5175-5195

    • ⏱ 2021-12-24 00:02:16
  • 📌 契约通常隐含在微服务实现的早期或者初期。它们通常是通过文档或者惯例来体现的 ^31151874-24-5650-5687

    • ⏱ 2021-12-24 00:03:12
  • 📌 order服务控制其他服务的动作以将订单提交到市场 ^31151874-24-5052-5077

    • ⏱ 2021-12-24 00:13:30
  • 📌 通过事件来对各个服务的功能进行编排,弱化order服务的协调者角色。 ^31151874-24-7367-7401

    • ⏱ 2021-12-24 00:14:21

第3章 微服务应用的架构

  • 📌 平台层、服务层、边界层和客户端层 ^31151874-31-1054-1070
    • ⏱ 2021-12-25 02:11:19

3.2 微服务平台

  • 📌 微服务平台层的功能 ^31151874-33-1028-1037

    • ⏱ 2021-12-25 13:35:04
  • 📌 在标准的云环境中运行微服务所需的部署配置 ^31151874-33-1908-1928

    • ⏱ 2021-12-25 13:40:58

3.3 服务层

  • 📌 实现业务功能和技术功能的微服务 ^31151874-34-1315-1330

    • ⏱ 2021-12-25 13:52:42
  • 📌 聚合器服务通过将底层服务的数据进行关联来实现查询服务,协调器服务会向下游服务发出各种命令来编配它们的行动 ^31151874-34-2591-2643

    • ⏱ 2021-12-25 13:57:02

3.4 通信

  • 📌 用作代理的工具包括Kafka、RabbitMQ和Redis。这些工具的意义并不相同:Kafka专门研究的是海量的、可重复的事件存储,而RabbitMQ提供了一套高度抽象的消息中间件(基于AMQP协议)。 ^31151874-35-3663-3764
    • ⏱ 2021-12-25 16:35:57

3.5 服务边界

  • 📌 边界层还可以实现一些其他面向客户端的功能:认证和授权——验证API客户端的身份和权限;限流——对客户端的滥用进行防卫;缓存——降低后端整体的负载;日志和指标收集——可以对客户端的请求进行分析和监控。 ^31151874-36-1560-1767

    • ⏱ 2021-12-25 17:04:29
  • 📌 API网关、服务于前端的后端以及消费者驱动的网关。 ^31151874-36-2388-2413

    • ⏱ 2021-12-25 17:09:36
  • 📌 API网关处理客户端请求 ^31151874-36-3560-3572

    • ⏱ 2021-12-25 17:15:43

4.2 按业务能力划分

  • 📌 被划为业务能力一类的微服务直接反映的是业务目标。 ^31151874-41-1208-1232
    • ⏱ 2021-12-27 11:03:09

5.1 分布式应用的事务一致性

  • 📌 将重要的编配职责交给事务管理器同样违背了微服务的核心原则:服务自治。最糟糕的情况下,我们的服务都只是默默地对数据进行CRUD操作,系统中最有意义的功能反而完全是由事务管理者来封装完成的。 ^31151874-49-2955-3048
    • ⏱ 2021-12-27 16:41:29

5.3 Saga

  • 📌 Saga是一组互相协作的本地事务序列;在Saga中,每一步的操作都是由前一个步骤所触发的。 ^31151874-51-418-463

    • ⏱ 2021-12-27 17:00:59
  • 📌 在Saga中,我们会用补偿操作来撤销之前的操作,并让系统恢复到更一致些的状态。 ^31151874-51-2225-2264

    • ⏱ 2021-12-27 17:04:08
  • 📌 补偿操作或者编配器自身同样可能会出现故障。我们在设计补偿操作时,就应该将其设计为可重试的并且没有意料之外的副作用(比如,退两次费用)的安全操作。 ^31151874-51-8173-8245

    • ⏱ 2021-12-27 17:27:22
  • 📌 不同于ACID类型的事务,Saga并不具备隔离性。每个本地事务的结果对其他事务而言都是立即可见的。这种可见性意味着一个给定的实体可能会同时参与到多个并行的Saga中。因此,开发者在设计业务逻辑时,就需要提前预见到这种中间态并处理这种问题。 ^31151874-51-8961-9080

    • ⏱ 2021-12-27 17:33:17
  • 📌 处理这种Saga交叉(图5.12)的情况有3种常用的策略:短路、加锁和中断。 ^31151874-51-9252-9290

    • ⏱ 2021-12-27 17:35:02
  • 📌 微服务应用中的一致性策略 ^31151874-51-10471-10483

    • ⏱ 2021-12-27 17:49:48
  • 📌 事件溯源(event sourcing)模式:完全用对象身上所发生的一系列的事件来表示状态,而不是用实体状态信息来表示所发布的事件消息。如果想要获取某个实体在指定时间的状态,开发者就需要聚合在此之前的所有事件。比如,设想这样的order服务:在传统的持久化方案中,我们一直都是假定数据库存储的是订单最新的状态;在事件溯源的方案中,我们保存的是订单状态的修改事件,我们可以通过复现这些事件来获取订单当前的具体状态。 ^31151874-51-11292-11505

    • ⏱ 2021-12-27 17:57:19

5.4 分布式世界中的查询操作

  • 📌 CQRS将服务分成了命令和查询两部分,每一部分分别由不同的数据存储来提供支持 ^31151874-52-5757-5796

    • ⏱ 2021-12-27 21:11:40
  • 📌 对查询数据视图的更新延迟会导致发起的请求返回不一致的结果 ^31151874-52-7885-7913

    • ⏱ 2021-12-27 21:33:27
  • 📌 3种处理CQRS中的查询复制延迟问题的策略 ^31151874-52-8531-8552

    • ⏱ 2021-12-27 21:35:03
  • 📌 开发者可以采用图5.20所示的3种策略:乐观更新、轮询以及发布-订阅。 ^31151874-52-8268-8303

    • ⏱ 2021-12-27 22:20:11
  • 📌 界面可以一直轮询对应的查询API,直到所期望的修改生效。在启动一个命令时,客户端可以设置一个版本号,如时间戳。对于后续的查询,客户端可以一直轮询,直到服务器返回的版本号等于或者大于指定的这个版本号,这表示查询数据模型已经成功更新体现了最新的状态。 ^31151874-52-8979-9102

    • ⏱ 2021-12-27 22:21:48

6.1 可靠性定义

  • 📌 在设计服务时,我们需要采取一种防御型的方式来满足3个目标:对于无法避免的故障要降低其发生率;对于无法预测的故障要控制其连锁影响,不要产生系统层面的影响;故障发生后,能够快速恢复(理想情况下可以自动恢复)。如果能够实现这些目标,那么服务的可用时间以及可用性最终也会达到最大化。 ^31151874-56-2830-2996
    • ⏱ 2021-12-27 22:44:34

6.2 哪些会出错

  • 📌 服务之间的通信也会出现故障,DNS、消息传递和防火墙都是可能的故障源。 ^31151874-57-3360-3395

    • ⏱ 2021-12-27 22:57:12
  • 📌 表6.2 微服务应用的通信故障源 ^31151874-57-3469-3485

    • ⏱ 2021-12-27 23:07:47
  • 📌 表6.1 微服务应用硬件层的故障原因 ^31151874-57-2688-2706

    • ⏱ 2021-12-27 23:07:59
  • 📌 表6.3 依赖相关的故障源 ^31151874-57-4275-4288

    • ⏱ 2021-12-27 23:08:12
  • 📌 连锁故障是一个“正反馈”的例子:某个事件对系统产生了干扰进而造成一些影响,而这个影响反过来又强化了最初的干扰程度。 ^31151874-57-5244-5301

    • ⏱ 2021-12-27 23:15:29
  • 📌 transaction服务过载导致某些请求失败,相应地,holding服务会重新发起请求,这进一步增大了holding服务的响应时间 ^31151874-57-8160-8226

    • ⏱ 2021-12-27 23:26:35

6.3 设计可靠的通信方案

  • 📌 永远要限制重试的总次数;使用带抖动的指数退避策略来均匀地分配重试请求和避免进一步加剧负载 ^31151874-58-5572-5616

    • ⏱ 2021-12-27 23:52:32
  • 📌 如果某个服务的依赖项出现了故障,我们可以考虑4种后备方案:优雅降级、缓存、功能冗余和桩数据。 ^31151874-58-5871-5917

    • ⏱ 2021-12-27 23:53:29
  • 📌 一种更加优雅的方式是为整个操作设置一个绝对的期限时间,然后将剩余时间传给下游协作方。 ^31151874-58-10095-10137

    • ⏱ 2021-12-28 00:08:49
  • 📌 如果在一定时间窗口内失败数或者失败率超过某个阈值,这时断路器就会被断开。 ^31151874-58-11499-11535

    • ⏱ 2021-12-28 00:27:50
  • 📌 并在可能的情况下执行适当的后备方案——返回一个桩消息、路由到其他服务或者返回缓存的数据。 ^31151874-58-11572-11616

    • ⏱ 2021-12-28 00:28:07
  • 📌 断路器需要发送试验性的请求,以判断连接是否恢复到健康状态。 ^31151874-58-12499-12528

    • ⏱ 2021-12-28 00:29:18
  • 📌 与重试技术一样,应该利用带抖动的指数退避方法来安排这些尝试请求。 ^31151874-58-12612-12644

    • ⏱ 2021-12-28 00:30:12

6.4 最大限度地提高服务可靠性

  • 📌 我们可以基于两个标准来对健康检查分类:存活性(liveness)和就绪性(readiness)。 ^31151874-59-1470-1518

    • ⏱ 2021-12-28 13:17:13
  • 📌 常见的限流策略 ^31151874-59-3082-3089

    • ⏱ 2021-12-28 13:23:12
  • 📌 服务可以向调用方返回一个自定义报头,以告诉消费方剩余的可用请求量。按照这一要求,上游协作方应该将剩余可用请求量这一信息考虑在内,并据此调整发出的请求频率。这种技术也被称作背压(back pressure)。 ^31151874-59-3326-3429

    • ⏱ 2021-12-28 13:25:40
  • 📌 网络故障、虚拟机故障、数据库无法响应——故障无处不在!为了测试这些失败场景,我们就需要采用混沌测试的方式。 ^31151874-59-5804-5857

    • ⏱ 2021-12-28 13:35:13

6.5 默认安全

  • 📌 服务网格扮演的是代理的角色。 ^31151874-60-2301-2315
    • ⏱ 2021-12-28 13:52:18

8.4 构建服务工件

  • 📌 (1)将非敏感配置数据保存到源代码管理系统中,和服务一起进行版本控制(通常以.env文件保存)。(2)将密码凭据信息保存到一个单独的、受到访问限制的“保险库”中(如HashiCorp中最为出名的vault)。 ^31151874-74-11020-11153
    • ⏱ 2021-12-28 17:40:53

8.6 不停机部署服务

  • 📌 不停机部署有3种常见的部署模式。 ^31151874-76-549-565

    • ⏱ 2021-12-28 17:53:36
  • 📌 滚动部署 ^31151874-76-617-628

    • ⏱ 2021-12-28 17:53:52
  • 📌 金丝雀部署 ^31151874-76-793-805

    • ⏱ 2021-12-28 17:54:18
  • 📌 蓝绿部署 ^31151874-76-1057-1068

    • ⏱ 2021-12-28 17:55:06
  • 📌 在服务消费者对错误率高度敏感、无法接受不健康的金丝雀风险的情况下,这种方法比金丝雀部署模式更有效。 ^31151874-76-1117-1166

    • ⏱ 2021-12-28 17:55:40

9.2 集群部署

  • 📌 pod:单个容器或者联系紧密的要一起调度到同一台机器上的一组容器。 ^31151874-80-2328-2361

    • ⏱ 2021-12-28 19:25:45
  • 📌 kube-proxy——提供了一个网络代理,用于将请求直接发送到集群中的不同pod,以及在pod之间发送请求。 ^31151874-80-10033-10102

    • ⏱ 2021-12-28 19:51:22

10.4 降低部署影响以及实现功能发布的技术

  • 📌 暗发布可以在不向用户暴露功能的情况下,使用真实的生产环境流量验证新服务的功能和行为 ^31151874-86-1325-1366

    • ⏱ 2021-12-29 13:18:45
  • 📌 功能标记控制用户是否可以使用这些功能。 ^31151874-86-1735-1754

    • ⏱ 2021-12-29 13:21:05

11.1 稳固的监控技术栈

  • 📌 在从面向用户的系统中收集度量指标时,开发者应该关注四大黄金标志:时延、错误量、通信量和饱和度。 ^31151874-90-3223-3270

    • ⏱ 2021-12-29 13:45:26
  • 📌 将出错请求的时延值排除在这个公式之外是很重要的 ^31151874-90-3532-3555

    • ⏱ 2021-12-29 13:47:55
  • 📌 通信量这一标志衡量的是对系统的需求量。所监测的系统类型不同,度量的内容(如每秒的请求量、网络I/O等)也会差异很大。 ^31151874-90-3883-3941

    • ⏱ 2021-12-29 13:50:23
  • 📌 计量器是一种可以展示为任意单一数值的度量指标,数值可以增大或者减小。 ^31151874-90-4497-4531

    • ⏱ 2021-12-29 13:51:54
  • 📌 图开发者可以用直方图(histogram)对观测结果进行采样,并根据类型、时间等指标将其划分到不同的配置分类桶中。使用直方图的度量指标示例有请求时延、I/O时延和每个响应结果的字节数。 ^31151874-90-4616-4737

    • ⏱ 2021-12-29 13:53:49

12.2 生成一致的、结构化的、人类可读的日志

  • 📌 开发者同时还应该避免多行日志(一条日志记录占用多行),因为这会导致日志聚合工具在解析日志时将日志拆分成多个片段。这种日志很容易丢失某些与特定日志记录相关的信息,比如ID、时间戳或者来源。 ^31151874-97-2436-2529

    • ⏱ 2021-12-29 19:07:54
  • 📌 当开发者交叉引用来自多个数据源的数据时,请求ID、用户ID和其他唯一标识符是非常重要的。 ^31151874-97-1383-1427

    • ⏱ 2021-12-29 19:07:55
  • 📌 为了能够将数据关联起来并适当排序,开发者需确保将时间戳附加到日志记录上。 ^31151874-97-1003-1039

    • ⏱ 2021-12-29 19:07:56
  • 📌 建议开发者尽可能使用GMT/UTC来收集数据。 ^31151874-97-1115-1138

    • ⏱ 2021-12-29 19:07:57
  • 📌 一般来说,通常使用的日志等级有ERROR、DEBUG、INFO和WARN。 ^31151874-97-1992-2029

    • ⏱ 2021-12-29 19:07:57
  • 📌 开发者可以使用的典型数据来源包括主机名、类名或模块名、函数名和文件名。 ^31151874-97-1701-1736

    • ⏱ 2021-12-29 19:07:58

12.3 为SimpleBank配置日志基础设施

  • 📌 Logstash是一个服务器端的处理流水线,支持从多个来源获取数据,并在将数据发送到Elasticsearch之前对其进行转换。 ^31151874-98-2100-2164

    • ⏱ 2021-12-29 19:07:55
  • 📌 我们将使用Elasticsearch、Logstash和Kibana构建所提出的日志基础设施。此外,我们还将使用Fluentd把日志从应用推送到集中式的日志解决方案中。 ^31151874-98-1193-1277

    • ⏱ 2021-12-29 19:07:58
  • 📌 服务将把所有日志信息重定向到STDOUT(标准输出),运行Fluentd守护进程的代理将负责把这些日志推送到Elasticsearch。 ^31151874-98-1436-1504

    • ⏱ 2021-12-29 19:07:59

13.1 建设高效团队

  • 📌 开发团队应该对产品拥有完整的“设想-构建-运行”循环。 ^31151874-103-4435-4462
    • ⏱ 2021-12-29 22:09:30

读书笔记

本书评论