《微服务设计》第 2 章 演化式架构师

  • 2019 年 10 月 8 日
  • 筆記

第 2 章 演化式架构师

2.1 不准确的比较

  • 架构师的一个重要职责是,确保团队有共同的技术愿景,以帮助我们向客户交付他们想要的系统。在某些场景下,架构师只需要和一个团队一起工作,这时他们等同于技术引领者

2.2 架构师的演化视角

  • 因此架构师必须改变那种从一开始就要设计出完美产品的想法,相反我们应该设计出一个合理的框架,在这个框架下可以慢慢演化出正确的系统,并且一旦我们学到了更多知识,应该可以很容易地应用到系统中
  • 架构师的职责之一就是保证该系统适合开发人员在其上工作

2.3 分区

  • 作为架构师,不应该过多关注每个区域内发生的事情,而应该多关注区域之间的事情。这意味着我们应该考虑不同的服务之间如何交互,或者说保证我们能够对整个系统的健康状态进行监控

代码架构师

  • 架构师需要理解他们的决定对系统会造成怎样的影响。最低的要求是:架构师需要花时间和团队在一起工作,理想情况下他们应该一起进行编码。对于实施结对编程的团队来说,架构师很容易花一定的时间和团队成员进行结对。理想情况下,你应该参与普通的工作,这样才能真正理解普通的工作是什么样子。架构师和团队真正坐在一起,这件事情再怎么强调也不过分!

2.4 一个原则性的方法

  • “规则对于智者来说是指导,对于愚蠢者来说是遵从。” ——一般认为出自 Douglas Bader

2.4.1 战略目标

  • 如果你是制定公司技术愿景的人,那么你可能需要花费更多的时间和组织内非技术的部分(通常他们被叫作业务部门)进行交互

2.4.2 原则

  • 为了和更大的目标保持一致,我们会制定一些具体的规则,并称之为原则,它不是一成不变的。举个
  • 一般来讲,原则最好不要超过 10 个,或者能够写在一张海报上,不然大家会很难记住
  • Heroku 的 12 Factors(http://www.12factor.net)就是一组能够帮助你在 Heroku 平台上创建应用的设计原则

2.4.3 实践

  • 我们通过相应的实践来保证原则能够得到实施,这些实践能够指导我们如何完成任务。通常
  • 这些实践包括代码规范、日志数据集中捕获或者 HTTP/REST 作为标准集成风格等。由于实践比较偏技术层面,所以其改变的频率会高于原则

2.4.4 将原则和实践相结合

  • 关键是要有一些重要的原则来指导系统的演化,同时也要有一些细节来指导如何实现这些原则

2.4.5 真实世界的例子

  • 实践改动得很频繁,而原则基本上没怎么变
  • 更好的方式是,创造一些工具来保证我们所做事情的正确性

2.5 要求的标准

2.5.1 监控

  • 能够清晰地描绘出跨服务系统的健康状态非常关键。这必须在系统级别而非单个服务级别进行考虑。我建议确保所有的服务使用同样的方式报告健康状态及其与监控相关的数据
  • 你可能会选择使用推送机制,也就是说,每个服务主动把数据推送到某个集中的位置。你可以使用 Graphite 来收集指标数据,使用 Nagios 来检测健康状态,或者使用轮询系统来从各个节点收集数据,但无论你的选择是什么,都应尽量保持标准化。日志功能和监控情况类似:也需要集中式管理

2.5.2 接口

  • 选用少数几种明确的接口技术有助于新消费者的集成。使用一种标准方式很好,两种也不太坏

2.5.3 架构安全性

  • 一个运行异常的服务可能会毁了整个系统,而这种后果是我们无法承担的,所以,必须保证每个服务都可以应对下游服务的错误请求。没有很好处理下游错误请求的服务越多,我们的系统就会越脆弱
  • 返回码也应该遵守一定的规则。如果你的断路器依赖于 HTTP 返回码,并且一个服务决定使用 2XX 作为错误码,或者把 4XX 和 5XX 混用,那么这种安全措施就没什么意义了。对以下几种请求做不同的处理可以帮助系统及时失败,并且也很容易追溯问题
    • (1)正常并且被正确处理的请求
    • (2)错误请求,并且服务识别出了它是错误的,但什么也没做
    • (3)被访问的服务宕机了,所以无法判断请求是否正常。如果我们的服务没有很好地遵守这些规则,那么整个系统就会更加脆弱

2.6 代码治理

  • 聚在一起,就如何做事情达成共识是一个好主意。我坚信应该使用简单的方式把事情做对。我见过的比较奏效的两种方式是,提供范例和服务代码模板

2.6.1 范例

  • 如果在系统中人们有比较好的代码范例可以模仿,那么他们也就不会错得很离谱
  • 理想情况下,你提供的优秀范例应该来自真实项目,而不是专门实现的一个完美的例子。因为如果你的范例来自真正运行的代码,那么就可以保证其中所体现的那些原则都是合理的

2.6.2 裁剪服务代码模板

  • 如果能够让所有的开发人员很容易地遵守大部分的指导原则,那就太棒了。一种可能的方式是,当开发人员想要实现一个新服务时,所有实现核心属性的那些代码都应该是现成的
  • 针对自己的开发实践裁剪出一个服务代码模板,不但可以提高开发速度,还可以保证服务的质量

2.7 技术债务

  • 有时候可能无法完全遵守技术愿景,比如为了发布一些紧急的特性,你可能会忽略一些约束。其实这仅仅是另一个需要做的取舍而已
  • 愿景短期可能会带来利益,但是长期来看是要付出代价的
  • 架构师应该能够提供一些温和的指导,然后让团队自行决定如何偿还这些技术债务。而其他的组织就需要更加结构化的方式,比如维护一个债务列表,并且定期回顾

2.8 例外管理

  • 有时候我们会决定针对某个规则破一次例,然后把它记录下来。如果这样的例外出现了很多次,就可以通过修改原则和实践的方式把我们的理解固化下来。举个例子,可能我们有一个实践论述应该总是使用 MySQL 做数据存储,但是后来有足够的证明表明在海量存储的场景下应使用 Cassandra,这时就可以对实践进行修改:“在大多数场景下使用 MySQL 做存储,如果是数据快速增长的场景,可以使用 Cassandra。”
  • 个人非常支持使用拥有更好自治性的微服务团队,他们有更大的自由度来解决问题。如果你所在的组织对开发人员有非常多的限制,那么微服务可能并不适合你

2.9 集中治理和领导

  • 架构师的部分职责是治理。那么治理又是什么意思呢?COBIT(Control Objectives for Information and Related Technology,信息和相关技术的控制目标)给出了一个很好的定义:治理通过评估干系人的需求、当前情况及下一步的可能性来确保企业目标的达成,通过排优先级和做决策来设定方向。对于已经达成一致的方向和目标进行监督。——COBIT 5
  • 架构师会对很多事情负责。他们需要确保有一组可以指导开发的原则,并且这些原则要与组织的战略相符。他们还需要确保,以这些原则为指导衍生出来的实践不会给开发人员带来痛苦。他们需要了解新技术,需要知道在什么时候做怎样的取舍。他们还需要让同事也理解这些决定和取舍,并执行下去。他们还需要花时间和团队一起工作,甚至是编码,从而了解所做的决定对团队造成了怎样的影响
  • 我很喜欢的一种模式是,由架构师领导这个小组,但是每个交付团队都有人参加。架构师负责确保该组织的正常运作,整个小组都要对治理负责。这样职责就得到了分担,并且保证有来自高层的支持。这也可以保证信息从开发团队顺畅地流入这个小组,从而保证小组做出更合理的决定
  • 作为一名架构师,你必须要在团队驶向类似鸭子池塘这样的地方时抓紧他们。还有一点要注意的是,即使你很清楚什么是对的,然后尝试去控制团队,也可能会破坏和团队的关系,并且会使团队感觉他们没有话语权。有时候按照一个你不同意的决定走下去反而是正确的,知道什么时候可以这么做,什么时候不要这么做是很困难的,但有时也很关键

2.10 建设团队

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

2.11 小结

  • 一个演进式架构师应该承担的职责

愿景

  • 确保在系统级有一个经过充分沟通的技术愿景,这个愿景应该可以帮助你满足客户和组织的需求

同理心

  • 理解你所做的决定对客户和同事带来的影响

合作

  • 和尽量多的同事进行沟通,从而更好地对愿景进行定义、修订及执行

适应性

  • 确保在你的客户和组织需要的时候调整技术愿景

自治性

  • 在标准化和团队自治之间寻找一个正确的平衡点

治理

  • 确保系统按照技术愿景的要求实现
  • 演进式架构师应该理解,成功要靠不断地取舍来实现。总会存在一些原因需要你改变工作的方式,但是具体做哪些改变就只能依赖于自己的经验了。而僵化地固守自己的想法无疑是最糟糕的做法