服务注册和服务发现

服务注册简介

在服务治理框架或产品中,服务的注册中心是必不可少的,这里的注册中心也可以叫作 “服务中心”。已经部署的每个服务实例都会向这个注册中心发起请求,把自己的服务信息添加到注册中心里,如服务名称、IP地址、端口号、通信协议等服务信息。注册中心会维护这份服务的实例清单,有了注册中心之后,就不用开发人员或运维人员来维护各个服务的实例清单了,集群规模发生改变、服务实例数量的增加和减少、服务名称发生改变、服务实例部署的 IP 地址或端口号发生改变,这些情况发生时都会通知注册中心,注册中心会自动修改实例清单中的内容。

比如,订单微服务的实例运行在 IP 地址为 192.168.1.122 的 7010 端口和 IP 地址为 192.168.3.41 的 7020 端口上,菜品微服务的实例运行在 IP 地址为 192.168.1.102 的 9010 端口、IP 地址为 192.168.3.102 的 9010 端口和 IP 地址为 192.168.3.101 的 9020 端口上。当这些服务实例的进程全部启动时,会向注册中心依次发出通知,注册中心就会将这些服务的信息维护到实例清单中,如表 5-1 所示。

Table 1. 表5-1 服务实例数量和 IP 地址
服务名称 实例数量 实例 IP 地址

order-service

2

192.168.1.122:7010,192.168.3.41:7020

food-service

3

192.168.1.102:9010,192.168.3.102:9010,192.168.3.101:9020

当然,不同注册中心产品里实例清单的格式和记录的信息会有所不同,表 5-1 只是笔者做的简易版的总结。

每个服务实例在启动时都向注册中心发出通知,将自己的服务名称、服务 IP 地址等信息提交到注册中心,注册中心将这些信息维护到实例清单中,这个过程就是服务注册。

服务发现简介

由于在服务治理相关框架下工作,因此各个服务间的调用可以不再通过硬编码的方式指定具体的实例 IP 地址来发起通信请求,而是根据服务名称发起通信请求。在注册中心的作用下,服务间的通信就变得简单了。注册中心维护了服务信息,减轻了开发人员与运维人员的工作负担。比如,订单微服务想要与菜品微服务通信,因为两个微服务都与注册中心保持连接,所以调用方可以向注册中心查询目标服务并获取目标服务的实例清单,之后就可以对具体的某个实例进行访问了。

订单微服务想要调用菜品微服务,可以向注册中心发起查询服务的请求,服务中心会将名称为 food-service 的服务信息列表返回给订单微服务。此时有三个名称为 food-service 的可用实例,订单微服务会获取这个清单,可用的实例 IP 地址分别为 192.168.1.102:9010、192.168.3.102:9010、192.168.3.101:9020。当订单微服务需要发起调用的时候,便会从这三个可用的 IP 地址列表中通过某种负载均衡策略选择一个 IP 地址,并直接发起请求。通过注册中心返回的清单信息,调用方可以精准地定位目标微服务,进而直接发起请求,不需要通过中间代理。

关于服务的负载均衡策略,后续会单独讲解。

服务调用方会从服务的注册中心获取被调用方的服务列表,或者由服务的注册中心将被调用方的服务列表变动信息推送给服务调用方,这个过程叫作服务发现。

在引入服务治理后,服务的信息维护和调用过程变为图 5-13 中的情形。

第一步,服务注册。所有的服务实例在启动时都会向注册中心发送通知,将自己的服务信息提交到注册中心。如图 5-13 所示,服务的注册中心可以选择 EurekaConsulNacos 等产品,本书项目实战所选择的服务中心是 Nacos

第二步,服务发现。调用方从服务中心获取被调用方服务的所有实例信息,或者由注册中心将被调用方服务数据的变动信息推送给调用方,即调用方不会每次都向服务的注册中心发起请求去获取被调用方的实例信息。比如,调用方可以在请求一次后就将可用的服务数据缓存到本地,直到注册中心主动将被调用方的服务实例清单变更信息推送过来,再进行本地缓存数据的变更,不同的产品或应用场景在缓存和服务信息的更新机制上会有不同的实现策略。

第三步,服务通信。调用方从可用的服务列表中选取某一个 IP 地址,直接发起服务调用。

image 2025 04 16 10 52 46 562
Figure 1. 图5-13 引入服务治理后服务的信息维护和调用过程