[toc]
本文章为阅读这 微服务设计[美]Sam Newman 一书籍的读书笔记

第1章 微服务

1.1 什么是微服务

微服务就是一些协同工作的小而自治的服务

1.1.1 很小,专注于做好一件事

  • 单一职责原则:把因相同原因而变化的东西聚合在一起,把因不同原因而变化的东西分离开来(Robert C.Martin)

    • 在代码层面:代码的内聚性
    • 在服务层面:微服务
  • 服务越小,微服务架构的优点和缺点也越明显

    • 服务越小,带来的独立性的好处多但管理大量服务也会越复杂

1.1.2 自治性

  • 一个微服务就是一个独立的实体。它可以独立地部署在PAAS上,也可以作为一个操作系统进程存在。
  • 但我们应该尽量避免把多个服务部署到同一个机器上,尽管这种隔离性会引发一些代价,但它能够大大简化分布式系统的构建
  • 服务之间均通过网络调用进行通信,从而加强服务之间的隔离性,避免紧耦合
  • 服务会暴露出API(Application Programming Interface 应用编程接口),然后服务之间通过这些API进行通信。API的实现技术应该避免和消费方耦合。
  • 为了达到解耦的目的,需要正确地建模服务和API

1.2 主要好处

1.2.1 技术异构型

  • 在多服务协作的系统中,可以在不同的服务中使用最适合该服务的技术,尝试使用一种适用所有场景的标准化技术,会使所有场景都得不到好的支持

    • 例如:不同服务可以使用不同的数据库
  • 微服务可以帮助我们更快地采用新技术,并且理解到新技术地好处

  • 为了同时使用多种技术,会付出代价,比如一些组织会限制语言的选择,比如网飞和推特地技术基于JVM

  • 贯穿本书地一个问题:微服务如何寻找平衡

    • 第2章将会讨论如何做技术选择,其中主要专注于演进式架构
    • 第4章主要关注继承,将讨论如何避免服务间的过度耦合,从而可以彼此独立地进行技术演化

1.2.2 弹性

  • 在单块服务系统中,如果服务不可用,那么所有功能不可用。
    • 可以通过将同样的实例运行到不同地机器上来降低功能完全不可用的概率
  • 然而微服务系统本身就能很好地处理服务的不可用和功能降级问题

1.2.3 扩展

  • 庞大的单体服务,即便只有一小部分存在性能问题,也需要对整个服务进行扩展,如果使用较小的多个服务,则可以只对需要扩展的服务进行扩展

1.2.4 简化部署

  • 单体服务中,部署频率低,意味着两次发布之间软件有很多的功能增强,此时两次发布之间的差异越大,出错的机率越高
  • 微服务架构中,各个服务的部署是独立的,可以针对特定服务进行单个部署。如果真出了问题,只影响一个服务,且容易回滚

1.2.5 与组织架构相匹配

  • 微服务架构可以很好地将架构和组织架构相匹配,避免出现过大地代码库,从而获得理想的团队大小和生产力,服务的所有权也更好地可以在团队之间迁移,从而避免异地团队地出现。

1.2.6 可组合性

  • 在微服务架构中,根据不同的目的,人们可以通过不同的方式使用同一个功能,在考虑用户如何使用该软件时这一点尤为重要。
  • 单纯考虑桌面网站或移动应用程序的时代已经过去了,现在需要考虑的程序种类有 Web,原生应用,移动端Web,平板应用以及可穿戴设备等
  • 因此针对每一种程序都需要考虑已有功能组合来实现这些应用
  • 在微服务架构中,系统会提供很多接缝供外部使用,当情况发生变化时,可以使用不同的方式构建应用,而整体化应用程序只能提供一个非常粗粒度的接缝供外部使用

1.2.7 对可替代性的优化

  • 历史遗留系统,可能使用Fortran变体编写,且运行在几十年前就应该被淘汰的硬件上,但以为工作量大,而且风险很高,至今仍在运行
  • 而在微服务架构中,可以轻易地重写服务或删除不再使用的服务

1.3 面向服务的架构

  • SOA(Service-Oriented Architecture,面向服务的架构)是一种设计方法,其中包含多个服务,而服务之间通过配合最终会提供一系列功能。

  • 一个服务通常以独立的形式存在于操作系统进程中,服务之间通过网络调用,而非采用进程内调用的方式进行通信

  • 实施SOA时会遇到很多问题

    • 通讯协议(如SOAP)如何选择
    • 第三方中间件如何选择
    • 服务粒度如何确定
  • 就像认为XP或者Scrum是敏捷软件开发的一种方法一样,微服务架构也可以是SOA的一种特定方式

1.4 其他分解技术

  • 基于微服务架构主要有两个优势
      1. 具有较小的粒度
      1. 能够在解决问题的方法上给予你更多的选择

1.4.1 共享库技术

  • 基本上所有的语言都支持将整个代码库分解为多个库,这是一种非常标准的分解技术,库可以由第三方或者自己组织提供
  • 存在缺点:
      1. 无法选择异构的技术
      • 一般来讲,一种库中只能存在一种语言,或者至少在同一个平台上使用
      1. 会失去独立地对系统某一部分进行扩展的能力,除非是用的是动态链接库,否则每次当库有更新的时候,都需要重新部署整个进程
      1. 最糟糕的影响:缺少一个比较明显的接缝来建立架构的安全性保护措施,从而无法保证系统的弹性

1.4.2 模块

  • 有些语言提供了模块分解技术,允许对模块进行生命周期管理,这样就可以把模块部署到运行的进程中,并且可以在不停止整个进程的前提下对某个模块进行更改
  • 模块分解技术
    • OSGI(Open Source Gateway Initiative,开放服务网关协议)
    • Erlang
  • 缺点与共享库类似:大大限制我们采用新技术和独立队服务进行扩展的能力,且有可能会导致使用过度耦合的集成技术,同时也缺乏相应的接缝来进行架构的安全性保护

1.5 没有银弹 & 1.6 小结

  • 微服务不是免费的午餐,更不是银弹,如果你想要得到一条通用准则,那么微服务是一个错误的决定
  • 到目前为止,已经了解到
    • 什么是微服务
    • 微服务和其他组合技术有什么不同
    • 微服务的好处
  • 后续将讨论如何得到这些好处及如何避免一些常见的陷阱

第2章 演化式架构师

  • 本章中架构师职责的观点是作者个人简介,其希望能对象牙塔中的定义发起攻击

2.1 不准确的比较

  • 计算机行业很年轻,因此社会很难理解我们,我们也不清楚自己到底在干什么
  • 所以我们尝试借鉴其他行业,把自己称作软件“工程师”或建筑师,然而,建筑师和工程师所具有的精确性和纪律性是遥不可及的。在英国至少需要7年才能成为建筑师,而很多IT证书并没有什么价值。
  • 有些人想要得到认可,所以借鉴了这些广为人知的行业中的名词,这样借鉴也会造成两个问题
    • 首先,这么做的前提是我们应该清楚自己应该是干什么的,而事实并非如此
      • 建筑和桥梁倒塌的次数远比程序崩溃的次数少,所以和工程师比是不公平的
    • 其次,这种类比很奇怪
      • 如果将桥梁建筑和编程类似的话,那么建到一半可能会发现对岸比预想的要远50米,而且材质是花岗岩而不是泥土。
    • 事实上,我们要创造的东西从设计上来说就要足够灵活,有很好的适应性,并且能够根据用户的需求进行演化
  • 如今架构师的定义逐渐被人接受,本书将尽力去重定义它

2.2 架构师的演化视角

  • 与建筑师相比,在软件中有大量的需求变更,使用的工具和技术既有多样性。
  • 一个角色可以和架构师相类比:城市规划师
  • 架构师的职责之一就是保证该系统的开发人员适合在其上工作

2.3 分区

  • 与城市规划师类比
    • 区域-服务
    • 应更多关注服务之间的事情,而不是服务内部

2.4 一个原则性的方法

  • 做系统设计方面的决定通常是在取舍,而在微服务架构中,需要更多的取舍

  • 战略目标:架构师不需要定义战略目标,战略目标关心的是公司的走向以及如何让公司满意,这些目标的层次都比较高,但通常不会涉及技术层面

  • 原则:为了和大目标保持一致,我们会指定一些具体的规则,称为原则,但原则并不是一成不变的

  • 实践:我们通过实践来保证原则能够得到实施,这些实践能指导我们如何完成任务。

    • 通常实践是技术相关的,而且是底层的,包括代码规范,日志数据集集中捕获等
    • 实践应该巩固原则
  • 将原则和实践相结合

    • 原则和实践是相对的,比如,可以把使用HTTP/REST作为原则而不是实践,但关键是要有一些重要的原则来指导系统的演化
  • 真实世界的例子

    • 几年间,时间变动很频繁,而原则基本没有变
    • 上面提到的名词可以使用文档来职场,也可以提供示例代码,搞好的方法是创造工具保证事情的正确性

2.5 要求的标准

  • 系统应该由很多小但有生命周期的组件构成,这些组件之间有着紧密的联系。

  • 所以在优化单个服务自治性的同时,也要兼顾全局,一种能帮我们实现平衡的方法就是,清楚地定义出一个好服务应有的属性

  • 监控

    • 能够清晰地描绘出跨服务系统的健康状态十分关键,这必须在系统级别而非单个服务级别进行考虑
    • 建议所有的服务使用同样的方式报告健康状态及其监控的数据
  • 接口:选用少数几种明确的接口技术有助于使用者的集成。

  • 架构安全性:一个运行异常的服务可能毁了整个系统,因此要保证每个服务可以应对下游服务的错误请求。

2.6 代码治理

  • 达成共识的方法:

  • 范例:提供代码范例,当系统中有好的代码范例时,开发人员也不会错得离谱

    • 理想情况下,提供的优秀范例应当来自真是项目,而不是专门实现的完美例子
  • 裁剪服务代码模板

    • 当开发人员想要实现一个新的服务时,所有实现核心属性的那些代码应该是现成的
    • 针对自己的开发实践裁剪出一个服务代码模板,不但可以开发出开发速度,还可以保证服务的质量
      • 针对不同技术栈,都需要一个服务代码模板

2.7 技术债务

  • 有时为了实现紧急的特性,可能会忽略一些约束,短期内可能会获得利益,但长期是会付出代价的,这就是技术债务。
  • 系统的目标发生变化时,且与现有事实不符,此时也会产生技术债务

2.8 例外管理

  • 当系统偏离指导会发生什么?
    • 有时候我们会针对某个规则破一次例,然后把他们记录下来。如果这个例外出现了很多次,那就可以通过修改原则和实践的方法把我们的理解固化下来。

2.9 集中治理和领导

  • 架构师的部分职责时治理:

    • 治理通过评估干系人的需求,当前情况及下一步的可能性来确保企业目标的达成,通过排优先级和做决策来设定方向,对于已经达成一致的方向和目标进行监督
  • 架构师的一个职责是确保有一个技术愿景,那么治理就是要确保我们构建的系统符合这个愿景,必要时应对愿景进行演化。

  • 架构师需要确保有一组可以指导开发的原则,且这些原则要与组织的战略相符

    • 他们还需要确保,以这些原则为指导衍生出来的实践不会给开发人员带来痛苦。
  • 此时可以成立一个治理小组,小组由技术专家领导,且有一线人员

    • 一种模式是架构师领导这个小组,每个交付团队都有人参加,架构师负责确保该组织的正常运作,整个小组对治理负责

2.10 建设团队

  • 对于一个系统技术愿景的主要负责人来说,执行愿景不仅仅等同于做技术决定,和你在一起工作的人自然会做出技术决定

  • 对于技术领导者来说,更重要的是帮助你的队友成长,帮助他们理解这个愿景,并保证他们可以积极地参与到愿景的实现和调整中去。

  • 在单块系统中,人们为某些事情负责的机会非常少,而在微服务架构种存在多个自治的代码看,每个代码库有自己独立的生命周期,这给更多人提供了对单个服务负责的机会。帮助他们成长,同时通过分担责任也可以防止某一个人负担过重

2.11 愿景

  • 本书认为一个演进式架构师应承担的责任

    • 愿景
      • 确保在系统级有一个经过充分沟通的技术愿景,这个愿景应该可以帮助你满足客户和组织的需求
    • 同理心
      • 理解你所做的决定的客户和同时带来的影响
    • 合作
      • 和尽量多的同事进行沟通,从而更好地对愿景进行定义,修订及执行
    • 适应性
      • 确保在你的客户和组织需要的时候调整技术愿景
    • 自治性
      • 在标准化和团队自制之间寻找一个正确的平衡点
    • 治理
      • 确保系统按照技术愿景执行
  • 在下一章,让我们带着对架构师的认识开始寻找微服务之间的正确边界

第3章 如何建模服务

3.1 MusicCorp简介

  • 讨论想法的书最好有例子辅助,本书例子 在线零售商Musiccorp.
  • MusicCorp最初是实体店经营,在唱片收益跌入谷底后将注意力放到了网上
  • 它认为赢得世界的方法是,保证自己很容易对应用进行修改,这正是微服务的用武之处

3.2 什么样的服务是好服务

3.2.1 松耦合

  • 实现松耦合,那么修改一个服务就不需要修改另一个服务

  • 使用微服务的最重要一点:能够独立修改和部署单个服务而不需要修改系统的其他部分

  • 紧耦合的原因

    • 使用紧耦合的方式做服务间的集成
    • 过度的服务间的通信可能会导致紧耦合

3.2.2 高内聚

  • 内聚原因:改变某一行为时,只在一个地方进行修改,然后尽快发布

  • 否则,需要同时发布多个微服务才能交付这个功能

  • 找到问题域的边界就可以确保相关的行为能发在同一个地方,并且他们会和其它边界尽量以松耦合的形式进行通信

3.3 限界上下文

  • 在Eric Evans的领域驱动设计中,Evans引入了 限界上下文的概念
    • 他任务一个给定的领域包含多个限界上下文,每个限界上下文中的模型分成两部分,一部分需要和外部通信,另一部分不需要
    • 每个上下文都有明确的的接口,接口决定了它会暴露那些模型给其他上下文
  • 另一个限界上下文的定义:一个由显示边界限定的特定职责