一、背景
1.1、问题描述
在微服务架构中,远程调用时 URL 通常是写死的。例如:
String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
当更换机器或新增机器时,这个 URL 就需要跟着变更,需要通知所有的相关服务去修改。随之而来的就是各个项目的配置文件反复更新,各个项目的频繁部署。这种没有具体意义但又不得不做的工作,会让人非常痛苦。
1.2、解决思路
生活中,避免不了和各个机构(医院、学校、政府部门等)打交道,就需要保存各个机构的电话号码。如果机构换了电话号码,就需要通知各个使用方,但是这些机构的使用方群体是巨大的,没办法做到一一通知,怎么处理呢?
机构电话如果发生变化,通知 114。用户需要联系机构时,先打 114 查询电话,然后再联系各个机构。114 查号台的作用主要有两个:
- 号码注册:服务方把电话上报给 114
- 号码查询:使用方通过 114 可以查到对应的号码
同样的,微服务开发时,也可以采用类似的方案。
- 服务启动/变更时,向注册中心报道。注册中心记录应用和 IP 的关系。
- 调用方调用时,先去注册中心获取服务方的 IP,再去服务方进行调用。
1.3、什么是注册中心?
在最初的架构体系中,集群的概念还不那么流行,且机器数量也比较少,此时直接使用 DNS+Nginx 就可以满足几乎所有服务的发现。相关的注册信息直接配置在 Nginx。但是随着微服务的流行与流量的激增,机器规模逐渐变大,并且机器会有频繁的上下线行为,这种时候需要运维手动地去维护这个配置信息是一个很难的操作。所以开发者们开始希望有这么一个东西,它能维护一个服务列表,哪个机器上线了,哪个机器宕机了,这些信息都会自动更新到服务列表上,客户端拿到这个列表,直接进行服务调用即可。这就是注册中心。
注册中心主要有三种角色:
- 服务提供者 (Server):一次业务中,被其它微服务调用的服务。也就是提供接口给其它微服务。
- 服务消费者 (Client):一次业务中,调用其它微服务的服务。也就是调用其它微服务提供的接口。
- 服务注册中心 (Registry):用于保存 Server 的注册信息,当 Server 节点发生变更时,Registry 会同步变更。服务与注册中心使用一定机制通信,如果注册中心与某服务长时间无法通信,就会注销该实例。
他们之间的关系以及工作内容,可以通过两个概念来描述:
- 服务注册:服务提供者在启动时,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。
- 服务发现:服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。服务发现的一个重要作用就是提供给服务消费者一个可用的服务列表。
1.4、CAP 理论
谈到注册中心,就避不开 CAP 理论。 CAP 理论是分布式系统设计中最基础,也是最为关键的理论。
- 一致性 (Consistency):CAP 理论中的一致性,指的是强一致性。所有节点在同一时间具有相同的数据。
- 可用性 (Availability):保证每个请求都有响应(响应结果可能不对)。
- 分区容错性 (Partition Tolerance):当出现网络分区后,系统仍然能够对外提供服务。
举例说明:
一个部门全国各地都有岗位,这时候,总部下发了一个通知,由于通知需要开会周知全员,当有客户咨询时:
- 所有成员对客户的回应结果都是一致的(一致性)
- 客户咨询时,一定有回应(可用性)
- 当其中一个成员休假时,这个部门的其他成员也可以对客户提供咨询服务(分区容错性)
CAP 理论告诉我们:一个分布式系统不可能同时满足数据一致性、服务可用性和分区容错性这三个基本需求,最多只能同时满足其中的两个。
在分布式系统中,系统间的网络不能 100% 保证健康,服务又必须对外保证服务。因此 Partition Tolerance 不可避免。那就只能在 C 和 A 中选择一个。也就是 CP 或者 AP 架构。




