这样才能真正地理解服务治理的核心思想。
分布式系统指的是通过网络连接让多台计算机协同解决单台计算机所不能解决的计算、存储等问题,多台计算机之间通过 RPC 方式通信。
在使用分布式系统前,首要解决的问题是如何拆解当前面临的问题。通过使用多台计算机分布式解决问题,让分布式系统中的每台机器都负责解决原问题的一个子集。一般来说,可以使用横向拆分法或者纵向拆分法对复杂的系统进行拆分。
然而,虽然通过拆分法解决了计算或存储的问题,但是使用分布式技术进行开发会引发比单体应用更多的问题,比如网络异常、数据一致性及分布式系统性能等。因此,在使用分布式架构开发系统前,需要先深入理解分布式系统的概念和可能存在的异常。
分布式系统的副本指的是在分布式系统中为数据或服务提供的冗余。该副本可分为服务副本和数据副本两种类型。
对于分布式系统而言,服务副本非常容易控制,由于服务本身具备无状况特性,运维人员可以动态增加或者减少服务副本的数量,而不会影响服务接口返回数据的正确性。数据副本分布在不同的计算机上,从技术角度来看,数据的一致性面临着巨大的挑战。数据副本的一致性通常具有以下几种情况。
然而,分布式系统也存在一些复杂特性,比如分布式系统的三态性、异构性、透明性、并发性、可扩展性等。我们在应用分布式系统的过程中要仔细斟酌这些特性的优势和副作用。
RPC(Remote Procedure Call,远程过程调用)是一种进程间通信方式,也是一种技术思想。
使用 RPC 技术时,允许本地程序通过网络调用另一台服务器上的函数或者方法,具体调用过程一般由 RPC 框架实现,不用编码实现。即无论是调用本地函数还是调用远程函数,我们编写的调用代码在本质上基本相同。
RPC框架要向服务调用方和服务提供方屏蔽各类复杂性操作,比如负载均衡、序列化和反序列化、网络重试、超时等;
主要由客户端、服务器端和注册中心3种角色构成,整体架构如下图所示;

一次RPC调用流程主要由5部分组成,分别是客户端、客户端存根、服务器端存根、服务提供端和网络传输,其调用流程如下图所示。

业务在刚开始时都是单体应用,随着用户量和访问量的增加,在架构层面会发生变化,逐步由单体应用开发转为分布式应用开发,比如把单体应用中的每个模块都按照特定的方法拆分成一组独立的服务,服务与服务之间通过HTTP或者RPC方式调用。
随着业务量的逐步增加,服务的数量也逐步增加。这时维护服务的URL地址就变得非常麻烦,所以需要设计一套系统来统一管理每个服务所对应的URL地址,这套系统就叫作注册中心。
当有多个服务时,消费者需要根据规则来调用相关服务,实现软负载均衡,以达到资源利用率最大化的目的。因此,服务注册、服务发现、负载均衡、流量削峰、版本兼容、服务熔断、服务降级、服务限流等方面的问题,都是因服务拆分所引发的一系列问题。如何解决这些问题,让服务更稳定地运行,就叫作服务治理。
总体来说,服务治理指的是企业为了确保事情顺利完成而实施的内容,包括最佳实践、架构原则、治理规程、规律及其他决定性的因素。下面针对服务治理过程中的各个环节做相关说明。
(1)服务:它是分布式架构下的基础单元,包括一个或一组软件功能,其目的是不同的客户端通过网络获取相应的数据,而不用关注底层实现的具体细节。
以用户服务为例,当客户端调用用户服务的注册功能时,注册信息会被写入数据库、缓存并发送消息来通知其他关注注册事件的系统,但是调用方并不清楚服务的具体处理逻辑。
(2)注册中心:它是微服务架构中的“通讯录”,记录了服务和服务地址的映射关系,主要涉及服务的提供者、服务注册中心和服务的消费者。
在数据流程中,服务提供者在启动服务之后将服务注册到注册中心;
服务消费者(或称为服务消费方)在启动时,会从注册中心拉取相关配置,并将其放到缓存中。
注册中心的优势在于解耦了服务提供者和服务消费者之间的关系,并且支持弹性扩容和缩容。当服务需要扩容时,只需要再部署一个该服务。当服务成功启动后,会自动被注册到注册中心,并推送给消费者。
(3)服务注册与发布:服务实例在启动时被加载到容器中,并将服务自身的相关信息,比如接口名称、接口版本、IP地址、端口等注册到注册中心,并使用心跳机制定期刷新当前服务在注册中心的状态,以确认服务状态正常,在服务终止时将其从注册表中删除。服务注册包括自注册模式和第三方注册模式这两种模式。
(4)服务发现:使用一个注册中心来记录分布式系统中全部服务的信息,以便其他服务快速找到这些已注册的服务。其目前有客户端发现模式和服务器端发现模式这两种模式。
(5)流量削峰:使用一些技术手段来削弱瞬时的请求高峰,让系统吞吐量在高峰请求下可控,也可用于消除毛刺,使服务器资源的利用更加均衡、充分。
常见的削峰策略有队列、限频、分层过滤、多级缓存等。
(6)版本兼容:在升级版本的过程中,需要考虑升级版本后新的数据结构能否理解和解析旧的数据,新协议能否理解旧的协议并做出预期内合适的处理。这就需要在服务设计过程中做好版本兼容工作。
(7)服务熔断:其作用类似于家用的保险丝。当某服务出现不可用或响应超时的情况时,已经达到系统设定的阈值,为了防止整个系统出现雪崩,会暂时停止对该服务的调用。
(8)服务降级:在服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略性地降级,以此释放服务器资源,保证核心任务的正常运行。降级时往往会指定不同的级别,面对不同的异常等级执行不同的处理。
(9)服务限流:服务限流可以被认为是服务降级的一种。它通过限制系统的输入和输出流量来达到保护系统的目的。一般来说,系统的吞吐量是可以被测算的。为了保证系统的稳定运行,一旦达到阈值,就需要限制流量。限制措施有延迟处理、拒绝处理或者部分拒绝处理等。
(10)负载均衡策略:它是用于解决一台机器无法处理所有请求而产生的一种算法。当集群里的1台或者多台服务器不能响应请求时,负载均衡策略会通过合理分摊流量,让更多的服务器均衡处理流量请求,不会因某一高峰时刻流量大而导致单个服务器的 CPU或内存急剧上升。
像通过RPC的方式调用的分布式架构有很多,比较常见的就是:Dubbo,以及Spring Cloud中的组件Fegin,下面我再简单说一下两者的区别
其实两者之间并没有什么可比性,因为Dubbo的官方文档已经说过了Dubbo只是一个Java的高性能轻量级的RPC框架,他只是对RPC进行了一些封装,使其更高效;
而Spring Cloud的官方文档中指出Spring Cloud只是一个微服务架构的落地技术栈,他的重点在于提供良好的开箱即用的体验,它不同于dubbo这种通讯协议的封装,Spring Cloud的目的是快速的搭建一个微服务架构并且提供很多应用的组件,使服务能够快速的运行起来。
Spring Cloud的定位是一个微幅架构的一站式解决方案,所以这两者之间并没有什么可对比的。
如果真的要做对比的话,其实应该让Dubbo和Fegin做一个比较,Dubbo和Fegin在微服务体系下都是一个服务间通讯的组件,而dubbo在传输数据时,采用二进制的方式传输,其占用的宽带更少,而且更多的要在Spring Cloud中做一个基于Netty的长连接通讯的一个组件;
而Fegin则不同,他是基于Http的做的一个通讯,一般会采用JSON传输数据,其带宽消耗的更多,但是呢,相对Dubbo,Http的扩展能力更强,对于一些多语言的异构项目,其实Fegin是更加合适的。