1.1 原始分布式时代
调用远程方法面临的问题与解决方案:
- 远程的服务在哪里------服务发现
- 有多少个------负载均衡
- 网络出现分区、超时或服务出错怎么办------熔断、隔离、降级
- 方法的参数与返回结果如何表示------序列化协议
- 信息如何传输------传输协议
- 服务权限如何管理------认证、授权
- 如何保证通信安全------网络安全
- 如何令调用不同机器的服务返回相同的结果------分布式数据一致性
1.2 单体系统时代
单体架构:系统中主要的过程调用都是进程内的,不会发生进程间通信。
优点
- 对于小型系统------由单台机器就足以支撑其良好运行的系统,单体不仅易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法的调用过程都是进程内调用,不会发生进程间通信(Inter-Process Communication,IPC),因此也是运行效率最高的一种架构网络。
缺点
-
由于所有代码都运行在同一个进程空间之内,意味着如果任何一部分代码出现了缺陷,过度消耗了进程空间内的资源,所造成的影响也是全局性的,难以隔离的。譬如内存泄漏、线程爆炸、阻塞、死循环等问题,都将会影响整个程序。
-
同样的原因,单体架构无法做到单独停止、更新、升级某一部分代码等操作(通过 OSGi 这种运行时模块化框架可以实现),所以从可维护性来说,单体系统也是不占优势的。
1.3 SOA时代
SOA 架构(Service-Oriented Architecture),面向服务的架构是一次具体地、系统性地成功解决分布式服务主要问题的架构模式。
-
烟囱式架构(Information Silo Architecture),又名信息孤岛(Information Island),指的是一种完全不与其他相关信息系统进行互操作或才协调工作的设计模式。但是这样"独立拆分"的系统一方面是不太可能存在,另一方面也不是企业希望看见的。
-
微内核架构(Microkernel Architecture),也被称为插件式架构(Plug-in Architecture)。将需要共享的公共数据,以及被其他子系统使用的公共服务、数据、资源集中到一起成为一个被所有业务系统共同依赖的核心(Kernel,或 Core System),具体的业务系统以插件模块(Plug-in Modules)的形式存在。微内核假设系统中各个插件模块之间是互不认识的,不可预知系统将安装哪些模块因此这些插件可以访问内核中的一些公共资源,但不能直接交互。
-
事件驱动架构(Event-Driven Architecture),在子系统之间建立一套事件队列管道(Event Queues),来自系统外部的消息将以事件的形式发送至管道中,各个子系统可以自由获取或发布一些新的事件到管理队列中去,如此,每个子系统既能与其他子系统互动,又都是独立的,高度解耦的。
SOA 针对服务之间的松散耦合、注册、发现、治理、隔离、编排困难等,进行了更加系统性、具体的探索:
"更具体"
- 拥有领导制定技术标准的组织 Open CSA
- 有清晰软件设计的指导原则
- 明确了采用 SOAP 作为远程调用的协议,依靠 SOAP 协议族来完成服务的发布、发现和治理
- 利用企业服务总线(Enterprise Service Bus,ESB)消息管理来实现各个子系统之前的通信
- 使用服务数据对象(Service Date Object,SDO)来访问和表示数据
- 使用服务组件架构(Service Component Architecture,SCA)来定义服务封装形式和容器等
"更系统"
- SOA 的终极目标是希望总结出一套自上而下的软件研发方法论,希望做到企业只需要跟着 SOA 的思路,就能够一揽子解决掉软件开发过程中的全部问题。
SOA 在 21 世纪最初的十年里曾经盛行一时,最终却还是偃旗息鼓,SOAP 协议被边缘化的本质原因,是过于严格的规范定义带来的过度的复杂性。
1.4 微服务时代
微服务(Microservices)是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。
微服务的九个核心业务与技术特征:
- 围绕业务能力构建(Organized around Business Capability),有怎样结构、规模、能力的团队,就会产生出对应结构、规模、能力的产品。
- 分散治理(Decentralized Governance),服务对应的开发团队有直接对服务运行质量负责的责任,也应该有首不受外界干预地掌控服务各个方面的权力。
- 通过服务来实现独立自治的组件(Componentization via Services)
- 产品化思维(Products not Projects),避免把软件研发视作要去完成某种功能,而是视作一种持续改进、提升的过程。
- 数据去中心化(Decentralized Data Management),微服务明确地提倡数据应该按领域分散管理、更新、维护、存储,在单体服务中,一个系统的各个功能模块通常会使用同一个数据库;并且同一个数据实体在不同的服务的视角里,它的抽象形态往往也是不同的。
- 强终端弱管道(Smart Endpoint and Dumb Pipe),如果服务需要额外的通信能力,就应该在服务自己的 Endpoint 上解决,而不是在通信管道上一揽子处理。RESTful 风格的通信在微服务中会是更加合适的选择。
- 容错性设计(Design for Failure),不虚幻地追求服务永远稳定,而是接受服务总会出错的现实。
- 演进式设计(Evolutionary Design),容错性设计承认服务会出错,演进式设计则是承认服务会被报废淘汰。
- 基础设施自动化(Infrastructure Automation),使用 CI/CD 减少构建、发布、运维工作的复杂性。
1.5 后微服务时代
- 分布式架构系统不可避免的问题,如注册发现、跟踪治理、负载均衡、传输通信等,并一定是非由软件系统本身来解决。
- 以 Docker(前)、Kubernetes(后) 以代表的容器技术,提供了基础设施层面的解决方案。
- 但 Kubernetes 不能完美解决分布式系统的全部问题,因为处于应用系统与基础设施的边缘的问题,难以在基础设施层面中精细化处理。
- 被称为"服务网络"(Service Mesh)的"边车代理模式"(Sidecar Proxy)被引入解决这一问题。
- 由系统自动在服务容器(通常是指 Kubernetes 的 Pod)中注入一个通信代理服务器,以类似网络安全里中间人攻击的方式进行流水劫持,在应用毫无感知的情况下,悄然接管应用所有对外通信。
- 这个代理除了实现正常的服务间通信外,还接收来自控制器的指令,以实现熔断、 认证、度量、监控、负载均衡等附加功能
传统SpringCloud与Kubernetes提供的解决方案对比
边车代理流量示意
1.6 无服务时代
对软件研发而言,不去做分布式无疑是最简单的,如果单台服务器的性能可以是无限的,那架构演进的结果肯定会与今天有很大的差别。
绝对意义上的无限性能必然是不存在的,但云计算给相对意义上的无限性能提供了可能。
无服务只涉及现场内容:后端设施(Backend)和函数(Function)
- 后端设计是指数据库、消息队列、日志、存储,等等这一类用于支撑业务逻辑运行,但本身无业务含义的技术组件,这些后端设施都运行在云中,无服务中称其为"后端即服务"(Backend as a Service,Baas)
- 函数是指业务逻辑代码,运行在云端的函数不必考虑算力问题,不必考虑容量规划,无服务中称其为"函数即服务"(Function as a Service,Faas)
无服务的愿景是让开发者只需要纯粹地关注业务,不需要考虑技术组件;不需要考虑部署过程;不需要考虑算力;不需要考虑运维;从而令生产力得到极大地解放。
无服务架构适用于短链接、无状态、适合事件驱动的交互形式,比如不需要交互的离线大规划计算,多数 Web 资讯类网站、小程序、公共 API 服务、移动应用服务商。另一方面,对于信息管理系统、网络游戏等应用,又或者说所有具体业务逻辑复杂,依赖服务端状态,响应速度要求较高,需要长链接等这些特征的应用,相对并不适合。
无服务天生"无限算力"的假设决定了它必须要按使用量(函数运算的时间和占用的内存)计算以控制消耗算力的规模,因而函数不会一直以活动状态常驻服务器,这导致函数会有冷启动时间,响应的性能不会太好。