先聊RPC

RPC(Remote Procedure Call)即远程过程调用,目的是让一个进程可以调用另一个进程中的某个方法/函数,就像调用自身的方法/函数一样,是实现进程通信的一种技术手段,服务器-客户端(Client/Server)模式。

RPC过程

因为RPC多用于分布式下进行不同子系统/模块远程调用,所以,一次RPC调用,和一般的网络通信的过程类似是对称的。

比如,现在有两台服务器A,B,而B中存在一个发邮件的方法,A需要调用B的发邮件方法,向客户发送邮件,此时A会将自己要访问B中发邮件方法的具体方法名,参数进行序列化,然后通过网络发送到B,而B接收到这个请求的时候,对消息进行反序列化,得到其中的方法名称,参数等信息,调用本地的发送邮件的方法,向客户发送一封邮件,将发送状态作为返回值进行序列化后通过网络发送给A,这样就完成了一次RPC调用,原理如下:

一次简单的RPC流程

虽然RPC作为一种通信协议,但具体通信方式有很多种,可以通过Socket进行通信,或者TCP、HTTP

分布式服务化

一个大而全的单体系统,被拆分为由若干独立的子系统(或者称之为服务)组合(将这些子系统更进一步的拆分,让子系统中的某些功能构成一个模块/组件,这些组件相互独立,共同协作对外提供服务,即微服务)而成,这些子系统通常不直接对外提供服务,由特定的系统对外提供服务,这些子系统只被这个特定的子系统调用,从中拿到结果响应给客户端,而子系统间的调用,离不开RPC,这时整个系统,变成了一个分布式的系统,分散在不同机器,占用不同的端口,共同协作对外提供服务,在客户端看来就跟一个大而全的单体系统提供的服务没有任何区别。

当系统从单体变为分布式时,享受了分布式架构带来的福利,降低了整个系统的耦合,拆分后各个服务变得更单一,更易维护,整个系统的可扩展性得到了保证,然而,带来福利的同时也带来了新的问题,如果某个服务故障,可能导致整个系统崩溃,系统的可用性受到威胁,系统对外提供服务,通过多个内部服务相互调用后作出响应,服务间依赖关系,以及服务调用的中间技术,让整个系统的维护成本增加了,系统发生故障,需要从错综复杂的调用关系中定位问题,排查问题成本增加了,服务间通过网络通信来交换数据,当出现网络问题时要能有补救办法,拆分的服务太多,需要有一个统一的地方对服务进行管理

所以面对分布式系统,我们就需要考虑以下问题:

  • 多个相同的服务如何管理
  • 服务的注册发现机制
  • 如何对服务做负载均衡,路由等功能
  • 服务故障后的处理机制,熔断,限流,降级等治理能力
  • 服务调用失败的重试策略,服务检测的心跳机制
  • 整个系统的高可用、性能、监控等

服务治理

针对以上分布式带来的问题,我们需要有对应的办法解决它,这就引出了服务治理的概念,解决分布式环境下带来的问题,保证整个系统的可用性、可维护性、可扩展性等非功能性需求。

注册中心

当整个系统由多个服务组成,那么这些服务,如何暴露自己,让别的服务可以访问,服务数量越来越多,每个服务分别在不同的地方,要查看目前暴露的服务,就需要到服务所在位置进行确认,导致管理成本增加,如何降低服务的管理成本。这就需要有一个地方,专门用来保存服务,服务要对外暴露自己,就在这个地方登记一下自己的信息,服务需要调用时,就在这个地方找要调用的服务,然后完成服务调用,当某个服务不对外提供服务时,就在这个地方,把自己登记的信息注销掉,除了服务主动的往这里发送信息外,这个地方也要能主动向已经在它这里注册的服务发送信息,确保当某个服务发生意外情况,不能对外提供服务了,也能及时感知到,主动将服务信息注销,这个地方就是所谓的注册中心。

配置中心

通过注册中心,让组成系统的各个服务可以在一个专门的地方得到有效的管理,降低了服务维护成本,那服务的管理和暴露问题解决了,就到了服务内部,每个服务提供的功能不同,所在的位置也不同,当然其配置也不同,需要对某个服务的配置做相应的修改时,同样的要去到服务所在位置进行修改,如果有50个服务配置需要修改,分布在50台机器上,那么我们需要依次登陆50台机器进行修改,重启服务,如果服务做了集群,每个服务存在多个副本,那么每个副本也需要去修改,那维护成本自然就高了。

这时候就应该像前面注册中心一样,也需要有一个专门的地方,来管理服务的配置信息,每个服务的配置,同一发送到这个地方,需要对某个服务或者某个服务集群的配置进行修改,只需要到这个专门的地方修改对应服务的配置就好了,这个地方将修改后的信息,通知到对应的服务或集群根据下发的配置,动态的更改运行时状态,这就是配置中心

元数据中心

通过配置中心和注册中心,服务的注册发现,服务的运行状态动态调整(比如,更改服务日志打印的级别,线程池参数修改,修改服务断线重连策略,心跳检测间隔,熔断阈值,降级配置等),使得整个系统的可维护性得到了提高,降低了系统的维护成本,同时,服务之间的调用可以做到端到端的调用,中间不会经过任何中间节点转发,但相对的,调用时,也就会需要传输更多的服务信息,来确保服务调用的准确性,这同时也站用了更多的传输资源,如果能像之前那样,将每个服务的描述信息,抽象出来独立存放到一个专门的地方,那么就可以减少调用所传输的数据,减少资源的占用,即所谓的元数据中心,通常,元数据中心存放的数据也就是整个业务的核心模型,但元数据中心,相比注册中心和配置中心,一般情况下其重要程度不如其他两个。

三个中心解决的问题

通过以上三个中心,我们解决了分布式环境下,服务的注册发现问题,多个相同的服务统一管理的问题,与服务本身以及服务运行时密切相关的全局配置信息的集中管理,这些被解决的问题,都有一个共同点:服务的维护性,一切都是为了让服务更易维护。

负载均衡与路由

负载均衡指的是从一些可用的服务器中选择一台服务器提供服务,路由的意思是过滤,从一些可用的服务器中,选择一部分服务器,一般路由都搭配负载均衡一起使用,通过路由过滤出一部分服务器,再从这一部分服务器中,选择一台服务器提供服务。通过负载均衡和路由,能有效的把系统的流量分摊到每台服务器上,这样保证了服务器不会因为接收的流量太大而崩溃,从而延长了系统对外提供服务的时间,提升了整个系统的可用性。

小结

以上是项目架构,从单体架构走向分布式架构乃至微服务架构时需要考虑的问题,以及一些比较通用的解决方案,当然,分布式情况下遇到的问题,远不止这些,比如,服务异常,为了保证异常的影响范围,需要对服务做熔断,系统降级的功能,当流量太大,需要考虑服务器最大处理能力,进行限流,为了确保系统不会在出事时才被察觉,需要采集系统的各个指标数据,对可能发生异常的情况做预警,监控系统的健康状况,以及分布式下系统保证幂等,跨节点事务等等问题。

Q.E.D.