[理论]生产微服务-1.微服务的简介

背景

微服务究竟是什么?为什么要使用微服务?怎么设计以及开发微服务项目?对于这致命问题三连,应该怎么回答?从开发至今,接触了蛮久的微服务项目,对于这些问题也很少去关注。我想诸君也有想过这些问题。我之前有主导过单体应用重构微服务的项目,当时主要是有新需求的场景,而旧应用已经满目疮痍,非常重,并且CTO也一直有重构项目的想法,多个需求点集合就有了放任我设计微服务的工作。设计和开发过程中也当然遇到了很多问题,虽然如此,但对于微服务的疑问却迟迟没有解决。最近有幸看到Uber的SRE(网站可靠性工程师) Susan J.Fowler写的一本书《生产微服务 在工程组织范围内构建标准化的系统》就是介绍微服务相关内容,遂分享在博客中。内容也会结合Chris Richardson大神的《Microservices Patterns》(微服务架构设计模式)这本书观点。

内容

从单体引用到微服务

我要重构的项目是12年的项目,项目设计之初就是使用JSP + SpringMVC + Hibernate的一个前后端结合的项目,项目依赖的Tomcat作为Sevlet容器。开发至今已经9年多了,是个非常典型的单体项目。

@startuml
cloud {
  [前端客户端]
  [后端]
}
database "Mysql" {
  frame "Foo" {
    [数据库]
  }
}
[User] --> [前端客户端]
[前端客户端] --> [后端]
[后端] --> [数据库]
@enduml

单体应用结构图.png
在公司初期。当然这种结构很符合开发人员少,业务场景不复杂的情况,对于运维来说也很简单。也许我们只要开发完在本地编译后直接上传解压到Tomcat的应用文件夹下即可。随着时间的积累以及功能递增和人员的变更,单体应用越来难于契合发展了。
它的问题包括:

  1. 功能以及组件复杂后运维人员需要全面了解机器、硬件、监控等内容,并且需要随时待命。因为运维环境不够完善,应用、组件、中间件等日志监控心痛不够完善,凌晨两三点处理数据,应用问题也都会有发生。
  2. 由于代码债务繁多,功能复杂,且在一个瓶子里,复杂性和耦合性高。
  3. 单体应用横向扩展所需要的资源,不能根据需要合理分配(如计算型和存储型)都只能使用相同资源。除了硬件资源,还有开发资源(如果单元测试)测试资源(自动化测试)和运维资源(编译打包),这些流程因为一个小改动而全局性的验证也屡见不鲜。

通常中后期遇到流量瓶颈时会采用横向扩展的方式:增加项目实例来应对流量压力。而因为单体应用的功能越来越多导致的CPU、内存等资源的问题通常是用纵向扩展的方式增加单台服务服务器的资源CPU、内存、硬盘等等。
单体应用扩展图.png
所以为了应对这些问题,微服务架构就出场了。
微服务的基本原理:让小型应用专注地做一件事。
微服务的目标:创建一组具备自治能力和自包含能力的独立应用,它们各自负责提供某一方面的功能。
微服务的好处:

  1. 减少技术债务
  2. 提升开发和测试效率
  3. 提升伸缩性
  4. 简化部署

微服务生态系统(重要)

按照Chris Richardson的说法从来没有一个微服务这种概念,微服务(Microservice)是一种架构,已经系统组织的形式,准确的来说服务(Service)才是一等公民。
大型的微服务环境的复杂性和热带雨林、沙漠或大洋的生态复杂性有得一比。可以将微服务组成的系统看成是微服务生态系统。

在一个设计良好的微服务生态系统里,微服务与基础设施之间是分离的。微服务与硬件、网络、构建和部署管道、服务发现和负载均衡都是分离的。他们都是微服务生态系统基础设施的组成部分。如何以一种稳定可靠地、可伸缩的、可容错的方式来构建、维护和标准化基础设施、是微服务运维的根本
基础设施必须能够支撑微服务生态系统。基础设施工程师和架构师的共同目标是为微服务的开发工作隐藏底层的运维细节,并构建一个稳定的、可伸缩的基础设施平台,让开发者可以轻松地上面构建和运行微服务。 在一个稳定的微服务生态系统里开发一个微服务应该和开发一个小型的标准应用一样,都需要一个出类拔萃的基础设施的支持。

微服务层次图.png

微服务的结构

硬件层
  1. 物理服务器
  2. 数据库
  3. 操作系统
  4. 资源隔离和资源抽象
  5. 配置管理
  6. 主机级别的监控
  7. 主机级别的日志
通信层
  1. 网络(Net)
  2. DNS
  3. 远程过程调用(RPC)
  4. 端点(Http)
  5. 消息传递(Kafka、RocketMQ、ActiveMQ、RabbitMQ...)
  6. 服务发现(etcd、Consul、ZooKeeper、Eureka、Nacos...)
  7. 服务注册
  8. 负载均衡(Ribbon、Loadbalancer)
应用平台层
  1. 内部自主开发工具
  2. 开发环境
  3. 测试、构建、打包和发布工具(Jenkins)
  4. 部署管道(Pipline)
  5. 微服务级别的日志(ELK)
  6. 微服务级别的监控(Skywalking、Zipkin、K8S)
微服务层
  1. 微服务
  2. 微服务相关配置

组织的挑战

微服务的结构具有非常好的伸缩性,但是就像书中提到的Frederick Brooks的《人月神话》中提到的"不管在技术还是管理领域,都不存在这样一种承诺,它能够在一段时期内为生产力、可靠性和简单性带来哪怕是一个数量级的增长。"微服务的优势当然是有成本的,也是有其相应的缺陷。所以说软件领域没有真正的银弹。
以下的4个挑战:

  1. 根据康威定律,组织结构决定了项目结构,由单体应用到微服务组织结构也需要对组织结构进行调整
  2. 之前的技术可能不够或实行微服务结构需要对其技术做出调整,实施和学习的成本都很高
  3. 系统失效的可能性会因此增加
  4. 工程资源和基础设施的争夺会变得激烈

反康威定律

康威定律:公司的沟通方式和组织方式决定了系统的架构。同样将康威定律反过来也是有效的。反康威定律:产品的架构决定了公司的组织结构。

技术蔓延

微服务化之后,相比之前的单应用的形式可以灵活使用更多的编程语言,以及配套环境,而这些新的框架以及语言的引入以及环境支持的语言和技术组件,都是会比之前情况复杂。技术的蔓延性是说一门语言的引入,其相应的的技术依赖以及技术扩展也会慢慢越来越多(所以统一语言或许是比较好的做法呢?)

更多失效可能性

相比原来单体的应用,将服务拆分之后,系统与系统直接的耦合性更小了,但模块也越多,即使是维护好也由于众多的模块服务导致的服务时效性问题更多,但是可靠性总是在一致性的对面,两者不能兼得。

资源竞争

当结构组织大了之后,就像自然界的生态系统一样,会存在类似的资源竞争问题。每个组织成员都会想要更多的工程资源做更好的事情,就会形成矛盾。

最后

以上是我对《生产微服务》第一章的见解
总的来说 软件领域从来没有银弹能解决所有问题的技术方案,只有更适合的方案。单体的应用是前期数据量低、业务简单、公司规模小的适配方案,但是到后期这三种要素都上升之后,微服务就是相对来说比较好的解决方案。微服务带来的组织管理、技术环境、以及失效的挑战也很多。但是能够使用这些微服务做好解耦,优化接口带来的收益也是不容小觑的。
使用微服务,架构师的价值是对业务开发人员能够提供无需关心基础的业务开发环境,为产品提供好的结构组织形式,与运维一起支撑系统的运转。

参考

  1. Susan J.Fowler《生产微服务 在工程组织范围内构建标准化的系统》第一章,2017年9月