在互联网早期即 Web 1.0的时代,当时流行的是单体应用,研发团队比较小,主要是外部网页,然后新闻门户等;到了新世纪的互联网时期即 Web 2.0 时代,网民数量大幅激增,电商社交这样巨无霸级别的互联网产品相继出现,因此流量及业务复杂度相较于上一个时代有了质的变化。此时出现了几百人甚至上千的研发团队在一个场景下,因此单体服务的弊端:例如研发效率等问题,就显现出来了。
这时出现了一个叫 SOA 的架构,其架构思路与微服务很像,它还有类似于 ESB 这种中心化组件,阿里的 HSF,包括后来开源的 Double,都是在这个阶段诞生的。
移动互联网时代出现之后,各种各样的 APP 出现,生活也开始全面的互联网化。大流量高并发以及规模化的研发团队变得越来越普遍,相应地对于高技术生产力的要求也在逐步提升,微服务的概念就应运而生。
微服务其实一直贯穿在整个架构的发展过程中。在 Java 的技术栈,类似于 Spring Cloud 、Double 这些框架都已经非常流行。不难发现整个社会已经步入数字化高速发展阶段,此时更大的问题蕴含其中,比如流量升高、整个应用的复杂度提升,研发团队扩大、对于效率的要求增高等。
大部分的公司或者早期的业务都会经历过这样一个过程,最初是客户端,此时访问的话需要通过一个入口,上图中的 SLB 是阿里云一个负载均衡服务,它相当于一个网络入口,可以对应到 ECS(ECS 就是阿里云的虚拟机)打到对应的单体的服务中,此时他们会共用一个数据库,这是第一个时期。
到第二个时期 SOA 架构,它带来了分治的思想,它会将一些业务去进行拆分。但此时它还并未做到服务与底层的拆分,如存储数据库的一个拆分,本质上还是共用一套数据库,所以它还是单体的架构。
到了微服务时期,如果客户端通过 SLB 访问了一个网关(如图所示),随后会转发到对应的服务,服务与服务之间会产生一些调用。每个服务会对应一个单独的数据库或者是缓存,并且每个服务通过类似于 Nacos 这种服务进行注册发现以及配置管理。微服务引入之后,虽然解决了架构业务的分离,让研发团队在某一个领域、业务能够做到精专。不过从整体架构来看就会发现,相较于之前它其实是更为复杂,所以也带来一些运维上的问题。
在单体架构中,对于单体应用来说,会发生边界不清晰,模块耦合、共享代码库容易冲突等问题,同时如果团队规模很大,此时协作效率也会相对较低。但是微服务架构中的核心就是解耦,如果做到拆分之后的解耦,就可以释放开发团队效率。
云原生是一个很宏观的概念,如果我们以微服务为起点来看云原生给微服务带来的变化与演进,可以帮助我们更好的理解什么是云原生。
微服务和单体应用的本质是什么呢?如图所示,它其实是把单体应用从一个巨型的应用拆分成数个微小的服务,然后协作来完成原先单体应用等效的业务服务。此时微服务与微服务之间会形成一个依赖关系,因此它可能会需要部署到一个或者多个资源上,这时的资源就是计算资源。
曾经的单体应用与资源之间的关系十分简单,单体应用的协同也都是一些内部协同,不存在外部动态的依赖。架构转换到微服务之后,由于外部依赖和节点数量的爆炸,整个体系会变成网状,管理起来十分复杂。超过 50% 的企业会觉得采用微服务架构,最大挑战是复杂的运维,即整个服务生命周期的管理。
如今,比较公认的一点是云原生的根基,在于容器与容器的管理编排(K8S)。而容器与 K8S 的技术能帮助我们解决微服务体系存在的繁杂运维问题。
首先不同的微服务之间会存在异构,就是一个团队,他在微服务体系下为了发挥最大效能,可能会允许不同的小团队采用不同的编程语言,甚至不同的运行环境来运行这些微服务。因此我们在运维和管理这些微服务时,最初都是没有统一的标准去处理这些异构环境的。这也就是为什么后来云原生的容器技术变得非常流行,因为其作用就是通过一层标准化的封装以及标准的运行时来限制微服务部署。这样从生命周期与管理角度来说,每一个微服务之间的差异变少,比较利于资源的调度。
随后基于容器调度,就衍生出了容器平台。容器平台是什么呢?它其实就是管理容器的。就 K8S 来说它能够非常标准化的将微服务最便捷的运行到底层的资源上。随后存储计算网络,它可以通过 K8S 这一层来进行统一的封装,一层抽象与封装,它就类似于云原生时代的操作系统。
它具体是提供哪些帮助呢?在 K8S 里面有个概念叫 POD ,POD 其实是一组容器的结合,与微服务实体生命周期的耦合。在一个 POD 里面,它可以运行一个或者是多个容器。
采用微服务架构时,一般都会把微服务运行的主体放在主容器里,也就是把微服务执行的主逻辑放在主容器里面,此时主容器的生命周期与 POD 的生命周期是完全耦合的。即 POD 什么时候消亡,微服的运行主体便何时消亡。除此之外我们还会运行一些边车容器,亦称 Sidecar,它主要是为主容器提供一些辅助的功能,如日志采集、网络代理身份鉴权等,都可以放在 Sidecar 里 。这样微服务就具备了一种超能力,除了提供自身核心业务以外,它还可以动态的提供额外辅助能力,让微服务的管理变得更加健壮与便捷。
此外 POD 这个模型还提供了许多非常有用的功能。比如状态信息,状态信息是指:POD 会提供一个标准的接口来显示运行时的状态。通过这个信息状态可以判断微服务或容器的整个运行状态。例如它是否正在运行中、业务是否已经准备好可以迎接流量的接入,它为整体的稳定性提供了保障。另一个是地址服务,地址服务就是每个 POD 会有一个标准化的 DNS 的地址服务,它对于需要统一暴露出来的 API ,像日志监控追踪能力都有非常大的帮助。通过 DNS 的日志地址来访问,或者暴露的可观测性的一些信息,可以及时发现运行时的问题。因此我们可以看到容器以及容器平台,能够在微观上帮微服务具备更多的能力。
图中为 4 种发布模型:
1、滚动更新,
2、固定更新。
3、蓝绿部署
4、金丝雀发布(灰度发布)
微服务将曾经单体时代的静态通信关系,通过拆分编成动态运行时。服务间的通信与协同通常需要单独管理,微服务框架帮助我们进行了每个服务通用功能的抽象与实现。
在抽象层面,包含两方面:业务逻辑与通信、流量以及服务治理能力。我们可以将底层一个通用能力抽象成一个具体的框架,但是不同微服务之间的框架,没办法实现相互间的调用。但是云原生时代它便可以使用不同的开发语言以及模型进行编程,实现微服务的研发。
Service Mesh 服务网格就是为了解决流量治理在多语言,多环境下的问题而出现的。
在数据层面,Sidecar 负责流量劫持转发以及管理,该功能典型 Sidecar 实现就是 Envoy。
如图它会先将上面那些从框架层面抽象出来,随后与业务直接进行解耦,并将通用能力放在 Sidecar 中,通过 Sidecar 之间的通信、转发去管理;这样便会使问题变得简单很多。而我们也只需要让流量管理和 Sidecar 之间进行通信,此时不同技术栈的微服务实例就能够互相进行通信了。
在管控层面,也需要一个组件来实现原微服务体系中的策略规则的管理,经典实现就是 Istio。
整体来说,除了数据层面,我们还需要管控层面的支持。比如原来在微服务体系中服务注册、服务发现以及流量观测等能力是需要管控层面的主线去完成的。我们可以通过管理 POD 中的流量以及数据层面的单点,让他们形成网状结构,变成一个集群。这个能力实现了流量的分配、安全、观测,有这些能力之后,它就组成了Service Mesh。
图中的编程模型与函数计算相关
请求驱动是基于请求的动态弹性伸缩,并简化请求处理的这种逻辑。微服务的调用,从流量进来后,一般会经过 4 层或者 7 层的负载均衡,随后分发到不同的微服务实例;但是在同一个微服务实例进程的内部,一般会有两个逻辑。第一个是请求管理,它可能是一个 HTTP 服务器,或者是一些 Handler,也可能是一些队列管理,请求分发能力的组成。而这些组成最终会将这些请求提交到第二部分,即请求处理中,而请求处理就是开发者需要去真正实现的一些逻辑。
比如说 Java Go 、Python,它们都有自己的一套请求管理逻辑。然后请求管理和请求处理之间形成强烈的耦合,这个实力它既包含请求的管理,又包含请求处理的逻辑。在这个架构下就不存在一个全局独立,且可以感知到请求以进行流量管理的控制层,只有到整个实例自身的处理层才如此解释请求。即便此时微服务实例已经过载,也很难将再这个请求转发到其他的微服务实例上进行负载均衡。所以请求驱动这个系统就是查数据、并解决这两个要素,而我们就是在做请求驱动的一个解耦。
如图所示,首先外部系统传输过来的请求会先进行标准化,会有一个适配器,标准化之后就会将其放在请求负载均衡器中,这个负载均衡器可以理解该请求本身的语义;然后它可以驱动并进行处理。当处理单元不够时,它可以通过管理器来进行扩容;而逻辑单元比较多时,它还可以进行缩容,这样变形成了一个动态的管理,可以为开发者节约非常多的成本。
请求驱动模型:
• 请求标准化
• 请求路由
• 处理管理
将请求标准化、请求路由、处理管理等组合起来,其实便是 Serverless 的概念。开发者根本不需要去关心 server ,只需要去专注业务逻辑便可以。这其实也是微服务体系与平台化的 Serverless 架构融合的过程。阿里云的 FC (函数计算)和 SAE(应用引擎) 都是以解决这些问题为核心的。
Serverless 其实经过了很多年的发展,其理念最早可以追溯到 2012年;而 2014 年,AWS 正式推出 Lambda,由此掀起了 Serverless 浪潮,但随后而来的是一段沉静的发展期。这种情况出现的原因是为什么呢?总体来看是因为函数计算的开发模式与原本模式有非常大出入,它更适合前端的,而不是 long running 形式的一些应用,它更偏向于一些基于请求的处理。因此一些需要长时间运行的服务,或应用架构,便不太能够享受到 Serverless 带来的弹性和降本提效的红利。
微服务架构的痛点
微服务的痛点就是稳定性。微服务带来了许多其他组件。例如服务发现、或是其他的一些工具类的产品。而这些在单体情况下会变得更加复杂化,因为整个架构变成网状结构。容器与容器平台,它其实在某些程度上是帮助我们承载微服务这部分的运维的,但是其本身,例如容器 K8S 它们都是存在一定复杂性的。
如 K8S 的这个架构图,是非常复杂的,同时也存在一些痛点:
• 容器镜像部署方式差异
• K8S 组件运维的复杂
• 学习成本
微服务比较理想的一个状态就是开发者只需要去关心架构中的业务系统,其他的网关 CICD 发布系统、验货流程,以及包括未付配套的注册中心、告警监控、分析日志,这些通通都不需开发者再去担心,开发者只需要去关心业务系统。对于开发者来说是最有吸引力的便是不用改变原本的开发方式的基础上只专注业务逻辑即可。
微服务体系在整个云计算发展的时代,它有不同的事件。例如最开始部署就是传统的 IT 设施,像 IDC 这种机房,微服务提供的是静态的物理计算资源。什么叫静态物理资源资源?比如说我们的一个服务器,有可能会造成资源的浪费。
然后到了第二步就是云托管时代,就是我们大家所熟知的 VM。在阿里的话就是 ECS ,它可以提供弹性的计算资源,但是它没有一个实质的改变,只是说资源上变成弹性,但它对于服务、微服务的一个部署,包括管理运维等本质上都没有太大变化。
但是到了第三阶段云原生时代,云平台、云服务都可以承担这些复杂的运维操作、配置、管理。如微服务提供的就是一个运行环境与平台,此时用户只需要去关心业务系统、以及如何实现业务系统即可。将复杂的技术变得越来越简单,让用户不再感知那些烦杂的操作,由平台代替用户去做重复的、难以维护的工作,这也符合整体计算机技术的发展方向。