单体应用——》SOA——》微服务

单体应用

所有功能都打包在一起,作为一个整体进行部署。
好处:容易开发、测试、部署
坏处

  • 复杂性高:代码多,十万行,百万行级别。加一个小功能,会带来其他功能的隐患,因为它们在一起。
  • 技术债务:人员流动,不坏不修,因为不敢修。
  • 持续部署困难:由于是全量应用,改一个小功能,全部部署,会导致无关的功能暂停使用。编译部署上线耗时长,不敢随便部署,导致部署频率低,进而又导致两次部署之间 功能修改多,越不敢部署,恶性循环。
  • 可靠性差:某个小问题,比如小功能出现OOM(Out Of Memory),会导致整个应用崩溃。
  • 扩展受限:只能整体扩展,无法按照需要进行扩展, 不能根据计算密集型(派单系统)和IO密集型(文件服务) 进行合适的区分。
  • 阻碍创新:单体应用是以一种技术解决所有问题,不容易引入新技术。但在高速的互联网发展过程中,适应的潮流是:用合适的语言做合适的事情。比如在单体应用中,一个项目用spring MVC,想换成spring boot,切换成本很高,因为有可能10万,百万行代码都要改,而微服务可以轻松切换,因为每个服务,功能简单,代码少。

    SOA

    SOA(Service Oriented Architecture),面向服务架构,拆分系统,用服务的流程化来实现业务灵活性。服务间需要某些方法进行连接,面向接口等,是一种设计方法,其中包含多个服务,服务之间通过相互依赖最终提供一系列的功能。一个服务,通常以独立的形式存在于操作系统进程中,各个服务之间通过网络调用,但是需要用这些方法进行服务组合,有可能还是单体应用。

微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想

微服务

  • 无严格定义。
  • 微服务是一种架构风格,将单体应用划分为小型的服务单元。
  • 微服务架构是一种使用一系列粒度较小的服务来开发单个应用的方式;每个服务运行在自己的进程中;服务间采用轻量级的方式进行通信(通常是HTTP API);这些服务是基于业务逻辑和范围,通过自动化部署的机制来独立部署的,并且服务的集中管理应该是最低限度的,即每个服务可以采用不同的编程语言编写,使用不同的数据存储技术。
  • https://www.martinfowler.com/articles/microservices.html

    微服务的特性

  • 独立运行在自己进程中。

  • 一系列独立服务共同构建起整个系统。
  • 一个服务只关注自己的独立业务。
  • 轻量的通信机制RESTful API
  • 使用不同语言开发
  • 全自动部署机制

    微服务组件

  • 服务注册与发现:服务Provider 将自身调用地址注册到服务注册中心,让服务Consumer能够找到自己;服务Consumer从服务注册中心找到需要调用的服务的地址,远程调用服务。

  • 负载均衡:服务Provider一般以多例的形式提供服务,负载均衡功能能够让服务调用方连接到合适的服务节点。并且,服务节点选择过程对服务调用方来说是透明的。
  • 服务网关:服务网关是服务调用的唯一入口,可以在服务网关中实现用户鉴权、动态路由、灰度发布、A/B测试、负载限流等功能

    1. 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
  • 配置中心:将本地化的配置信息(XML、yaml、properties等形式)注册到配置中心,实现程序包在开发、测试、生产环境中无差别性,方便程序包的迁移。

  • 集成框架:微服务组件都以职责单一的程序包对外提供服务,集成框架以配置的形式将所有微服务组件(特别是管理端组件)集成到统一的界面框架下,让用户能够在统一的界面送使用系统。
  • 调用链监控:记录一次请求的先后衔接和调用关系,并将这种串行或并行的调用关系展示出来。便于系统出错时能够方便找到出错点。
  • 支撑平台:系统微服务化后,各个业务模块经过拆分变得更加细化,系统的部署、运维、监控等都比单体应用架构更加复杂,这就需要将大部分的工作自动化。现在,Docker等工具可以给微服务架构的部署带来较多的便利,例如持续集成、蓝绿发布、健康检查、性能监控等等。如果没有合适的支撑平台或工具,微服务架构就无法发挥它最大的功效。 ```
  1. 蓝绿部署是不停老版本,部署新版本然后进行测试,确认OK,将流量切到新版本,然后老版本同时也升级到新版本。
  2. 灰度是选择部分部署新版本,将部分流量引入到新版本,新老版本同时提供服务。等待灰度的版本OK,可全量覆盖老版本。

灰度是不同版本共存,蓝绿是新旧版本切换,2种模式的出发点不一样。

<a name="Arevf"></a>
#### 微服务优点

1. 独立部署:不依赖其他服务,耦合性低,不用管其他服务的部署对自己的影响。
1. 易于开发和维护:关注特定业务,所以业务清晰,代码量少,模块变的易开发、易理解、易维护。
1. 启动快:功能少,代码少,所以启动快,有需要停机维护的服务,不会长时间暂停服务。
1. 局部修改容易:只需要部署 相应的服务即可,适合敏捷开发。
1. 技术栈不受限:java,node.js等
1. 按需伸缩:某个服务受限,可以按需增加内存,cpu等。
1. 职责专一:专门团队负责专门业务,有利于团队分工。
1. 代码复用:不需要重复写。底层实现通过接口方式提供。
1. 便于团队协作:每个团队只需要提供API就行,定义好API后,可以并行开发。
<a name="XIyMn"></a>
#### 微服务的缺点

1.  分布式固有的复杂性:容错(某个服务宕机),网络延时,调用关系、分布式事务等,都会带来复杂。 
1.  分布式事务的挑战:每个服务有自己的数据库,优点在于不同服务可以选择适合自身业务的数据库。订单用MySQL,评论用Mongodb等。目前最理想解决方案是:柔性事务的最终一致性。 
```shell
刚性事务:遵循ACID原则,强一致性。
柔性事务:遵循BASE理论,最终一致性;与刚性事务不同,柔性事务允许一定时间内,不同节点的数据不一致,但要求最终一致。

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。BASE理论是对CAP中AP的一个扩展,通过牺牲强一致性来获得可用性,当出现故障允许部分不可用但要保证核心功能可用,允许数据在一段时间内是不一致的,但最终达到一致状态。满足BASE理论的事务,我们称之为“柔性事务”。
  1. 接口调整成本高:改一个接口,调用方都要改。
  2. 测试难度提升:一个接口改变,所有调用方都得测。自动化测试就变的重要了。API文档的管理也尤为重要。推荐:yapi。
  3. 运维要求高:需要维护几十上百个服务。监控变的复杂。并且还要关注多个集群,不像原来单体,一个应用正常运行即可。
  4. 重复工作:比如java的工具类可以在共享common.jar中,但在多语言下行不通,C++无法直接用java的jar包。

    设计原则

  • 单一职责原则:关注整个系统功能中单独,有界限的一部分。
  • 服务自治原则:可以独立开发,测试,构建,部署,运行,与其他服务解耦。
  • 轻量级通信原则:轻,跨平台,跨语言。REST,AMQP 等。
  • 粒度把控:与自己实际相结合。 不要追求完美,随业务进化而调整。《淘宝技术这10年》。

    SpringCloud

    image.png
  1. 服务注册与发现组件
  • Eureka,基于REST风格的。
  • Zookeeper
  • Consul
  • Nacos等
  1. 服务调用组件
  • Hystrix(熔断降级,在出现依赖服务失效的情况下,通过隔离 系统依赖服务 的方式,防止服务级联失败,同时提供失败回滚机制,使系统能够更快地从异常中恢复)
  • Ribbon(客户端负载均衡,用于提供客户端的软件负载均衡算法,提供了一系列完善的配置项:连接超时、重试等)
  • OpenFeign(优雅的封装Ribbon,是一个声明式RESTful网络请求客户端,它使编写Web服务客户端变得更加方便和快捷)。
  1. 网关:路由和过滤。
  • Zuul
  • Gateway。
  1. 配置中心:提供了配置集中管理,动态刷新配置的功能;配置通过Git或者其他方式来存储。
  2. 消息组件:
  • Spring Cloud Stream(对分布式消息进行抽象,包括发布订阅、分组消费等功能,实现了微服务之间的异步通信)
  • Spring Cloud Bus(主要提供服务间的事件通信,如刷新配置)
  1. 安全控制组件:
  • Spring Cloud Security 基于OAuth2.0开放网络的安全标准,提供了单点登录、资源授权和令牌管理等功能
  1. 链路追踪组件
  • Spring Cloud Sleuth(收集调用链路上的数据)
  • Zipkin(对Sleuth收集的信息,进行存储,统计,展示)