[微服务设计][2][演化式架构师]

2 演化式架构师

在微服务架构下,我们需要做一些决定,比如

  1. 应该使用多少种不同的技术
  2. 不同的团队是否应该使用不同的编码规范
  3. 是应该合并多个服务还是把一个服务拆分为多个

2.1 不准确的比较

  • 架构师的重要职责

    1. 确保团队有相同的技术愿景,以帮助我们向客户交付他们想要的系统
    2. 保证该系统适合开发人员在其上工作
  • 我们把自己称为软件工程师(engineer)或者架构师(architect),但是对我们来说,工程师和架构师的精确度和纪律性是遥不可及的。建筑和桥梁倒塌的次数要比我们的程序崩溃的次数少的多

  • 我们要创造的东西从设计上说就是要足够灵活,有很好的适应性,并且能够根据客户的需求进行演化

  • 在我们这个行业。这种建筑师的视角会导致一些很糟糕的实践,人们视图通过大量的图表和文档创建出一个完美的方案,而忽略了很多基础性的未知因素。使用这种方式会导致人们很难真正理解实现起来的难度,甚至不知道这个设计能否奏效,想要对系统了解更多之后再对设计进行修改就更不可能了

2.2 架构师的演化视角

  • 我们应该设计出一个合理的框架,在这个框架下可以慢慢演化出正确的系统,并且一旦我们学到了更多知识,应该可以很容易地应用到系统中

  • 一个可以和IT架构师类比的角色: 城市规划师

  • 当用户对软件提出变更需求时,我们需要对其进行响应并作出相应的改变。未来的变化很难预见,所以与其对所有变化的可能性进行预测,不如做一个允许变化的计划。为此,应该避免对所有事情进行过于详尽的设计

2.3 分区

  • 区域的概念: 区域是我们的服务边界,或者是一些粗粒度的服务群组

  • 我们应该考虑不同的服务之间怎么交互,或者说保证我们能够对整个系统的健康状态进行监控。不应过度介入细节

  • 很多组织采用微服务是为了使团队的自治性最大化

  • 每个服务内部可以允许团队自己选择不同的技术栈或者数据存储技术,但是也不会无限制地允许团队选择任意技术栈

  • 但是我们要保证服务之间的交互是可控的,比如一个服务决定通过HTTP暴露REST接口,另一个用的是protocol buffers,第三个用的是Java RMI,这种设计就是糟糕的

2.4 一个原则性的方法

规划对于智者来说是指导,对于愚蠢者来说是遵从

2.4.1 战略目标

  • 通常我们不需要定义战略目标,战略目标层次一般很高,关心的是团队的走向问题

2.4.2 原则

  • 为了和更大的目标保持一致,我们会提出一些具体的规则,称之为原则
  • 例如,如果组织的一个目标是在其他国家快速增长业务,我们需要使用的原则可能是,整个系统必须能够方便的部署在相应的国家

2.4.3 实践

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

  • 通常这些实践都是技术相关的,而且都是比较底层的,所以任何一个开发人员都能够理解

  • 这些实践包括

    1. 代码规范
    2. 日志数据集中捕获
    3. 或者HTTP/REST作为标准集成风格等

2.4.4 一个例子

2.5 要求的标准

  • 我们需要给出一个好服务的特点
    • 它需要有什么样的能力才能保证系统是可控的
    • 并且它除了问题不会导致系统瘫痪

2.5.1 监控

  • 建议确保所有的服务使用先沟通的方式报告健康状况及其与监控相关的数据

2.5.2 接口

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

2.5.3 架构安全性

  • 一个运行异常的服务可能会毁了整个系统,而这种后果是我们无法承担的,所以,必须保证每个服务都可以应对下游服务的错误请求

  • 你可以至少保证每个下游服务使用它们自己的连接池,进一步让每个服务使用一个断路器

  • 我们应该对以下几种请求做不同的处理可以帮助系统及时失败

    1. 正常并且被正常处理的请求
    2. 错误请求,并且服务识别了它是错误的,但什么都没做
    3. 被访问的服务宕机了,所以无法判断请求

2.6 代码治理

  • 在各个服务中引入标准的做法是提供范例和服务代码模板

2.6.1 范例

  • 开发人员更喜欢可以查看和运行的代码,如果你有一些很好的实践希望别人采纳,那么给出一系列的代码范例会很有帮助

  • 如果在系统中人们有比较好的代码范例可以模仿,那么他们就不会错的太离谱

2.6.2 服务代码模板

  • 当开发人员想要实现一个新功能时,所有实现核心属性的那些代码都应该是现成的

  • DropwizardKaryon是两个基于JVM的开源微容器。它们会自动下载一系列第三方库,这些库提供一些特性,比如健康检查、HTTP服务、提供指标数据接口等

  • 针对自己的开发实践裁剪出一个服务代码模板,不但可以提高k开发速度,还可以保证服务的质量

2.7 技术债务

  • 我们的技术愿景本身有其道理,所以偏离了这个愿景短期可能会带来利益。但是长期来开是要付出代价的。可以使用技术债务的概念来帮助我们理解这种取舍

2.8 例外管理

  • 有时,我们会决定针对某个规则破一次例,并把它记录下来,这就是例外管理

  • 如果这样的例外出现了很多次,就可以通过修改原则和实践的方式把我们的理解固化下来

  • 例如: 我们有个实践论述是"总是使用mysql做数据存储",但是后来有足够的证据证明在海量存储的场景下应使用Cassandra,这时就可以进行修改:“在大部分场景下用Mysql存储,如果数据快速增长,则用Cassandra”