专栏目录
前言
大家好,我是「周三不Coding」。
在上一篇文章中,我们梳理了微服务技术架构脉络。今天,我们开始微服务架构中的第一个板块 —— 「服务发现与注册」。
请给我 15 分钟时间,我会从 2W1H
角度,梳理清楚注册中心全套知识点:
- Why – 为什么需要注册中心?(3 分钟)
- What – 什么是注册中心?(3 分钟)
- How – 如何对注册中心进行技术选型?(9 分钟)
对于每一个部分,为了使大家更加通俗易懂地理解与兼顾趣味性,咱们先讲故事,再说结论。
今天的故事从 ?小T 停车场项目升级 「微服务架构」 开始讲起,如果有不熟悉的同学,可以先看看专栏第一篇~
如果大家不想听故事,可以直接跳到每个部分的「总结」,不影响整体的阅读~
废话不多说,咱们快速进入正题!
为什么需要注册中心 & 什么是注册中心
故事
?小T 的停车场项目团队中存在两个服务,一个是车场服务,另外一个是商城服务,采用的是 「SOA 架构」。
为了适应新需求、新变化,他决定将其项目升级为「微服务架构」。
于是,他便首先开始做服务拆分,经过一番深思熟虑后,他将项目拆分为了「用户服务」、「商品服务」、「车场服务」、「订单服务」、「支付服务」、「优惠券服务」、「推荐服务」、「消息服务」等十余个服务。
想要看 ?小T 是如何拆分服务的,可以看看专栏第二篇,反正上班摸鱼,闲着也是闲着嘛~
但是,服务之间存在互相调用的情况,并且调用链条可能不止有两个服务,比如说:
- 「车场服务」或「商城服务」调用「推荐服务」获取推荐 ID 列表,并渲染首页;
- 「订单服务」调用「用户服务」获取用户信息,调用「支付服务」进行付款,后续「消息服务」向用户发送下订单以及支付成功消息
那么,这些服务之间如何互相通信呢?可以通过 TCP 协议或 HTTP 协议进行网络通信。
但机智的 ?小T 很快就意识了一个问题,既然要进行网络通信,那就必须知道各个服务的地址、端口、方法等基础信息。这些信息应该如何管理呢?
?小T 想到最为直接的方法就是,通过 Map
进行管理,key
为服务名称,value
为服务的基本信息。各个服务在调用其他服务之前,先到 Map
上通过服务名称找到对应的基本信息,然后发起请求调用。
但是他分析之后,认为这一方法不满足实际需求,仍需要进一步扩展。在实际的微服务场景中,当服务上下线时,其它各个微服务需要及时获取这一信息,以免出现消息滞后而造成调用失败的问题。
?小T 仔细想了想,认为如果要保证服务的高可用,短时间内很难造出一个合适的中间件轮子。
于是,他开始寻找开源的解决方案。经过一番调研后,他了解到了「注册中心」这一组件就是专门用于解决这一需求。
总结
微服务之间存在互相调用,既然涉及到调用,那么需要考虑网络通信,进而需要知道各个服务的地址、端口等基础信息。
因此,「注册中心」应运而生,其专门用于处理服务注册、服务信息查找、服务上下线通知。
更具体地来说,负责以下三类事项:
- 服务发现:客户端需要订阅注册中心。在需要远程调用时,从注册中心中获取信息,然后进行方法调用
- 服务注册:服务提供者将地址、接口、分组等信息存放在注册中心模块,当服务上线、下线均会通知注册中心
- 服务管理:提供服务的上下线管理、服务配置管理、服务健康检查等功能,以保证服务的可靠性和稳定性
具体流程为:
-
当服务提供者上线时,会通过注册中心,注册当前服务信息,即我们之前提到的服务地址、端口、方法等,交由注册中心进行管理。
-
当某一服务上线、下线或服务信息变更时,其他服务可通过如下方式获取到这一变更:
- 事件监听机制: 服务监听注册中心中被订阅服务的信息,当发生变化时,通过回调机制通知该服务。
- 定时拉取机制: 服务定时从注册中心中拉取服务列表并更新。
注册中心技术选型
前置知识:CAP 理论
CAP 理论是分布式系统中的重中之重!
CAP 是 Consistency(一致性) 、Availability(可用性) 、Partition Tolerance(分区容错性) 这三个单词首字母组合。
一致性(Consistency) : 所有节点访问同一份最新的数据副本
可用性(Availability) : 非故障的节点在合理的时间内返回合理的响应(不是错误或者超时的响应)。
分区容错性(Partition Tolerance) : 分布式系统出现网络分区的时候,仍然能够对外提供服务。
CAP 并不是简单的 3 选 2,因为分区容错性是必须实现的。以分区容错性作为前提,在一致性与可用性中做选择。
故事
?小T 经过调研之后,发现目前市面上主要有如下几种注册中心:
- Zookeeper
- Nacos
- Eureka
- Consul
首先,他对这 4 种注册中心进行了详细的调研:
-
Zookeeper
-
Zookeeper
通过znode
节点来存储数据。因此可以利用这一特性进行服务注册,节点用于存储服务 IP、端口、协议等信息。- 例如:服务提供者上线时,
Zookeeper
创建该节点 –/provider/{serviceName}:{ip}:{port}
- 例如:服务提供者上线时,
-
Zookeeper
提供Watcher
机制,可以监听相应的节点路径。因此我们可以利用这一机制监听对应的路径,一旦路径上的数据发生了变化,我们便向其他订阅该服务的服务发送数据变更消息。收到消息的服务便去更新本地缓存列表。 -
Zookeeper
提供心跳检测功能,定时向各个服务提供者发送心跳请求,确保各个服务存活。如果服务一直未响应,则说明服务挂了,将该节点删除。 -
Zookeeper
遵循一致性原则,即 「CP」- 对于注册中心而言,最重要的是可用性,我们需要随时能够获取到服务提供者的信息,即使它可能是几分钟以前的旧信息。
- 但是
Zookeeper
由于其核心算法是ZAB
,主要适用于分布式协调系统(分布式配置、集群管理等场景)。当master
节点故障后,剩余节点会重新进行leader 选举
,导致在选举期间整个Zookeeper
集群不可用。
-
-
Nacos
-
服务提供者启动时,会向
Nacos Server
注册当前服务信息,并建立心跳机制,检测服务状态。 -
服务消费者启动时,从
Nacos Server
中读取订阅服务的实例列表,缓存到本地。并开启定时任务,每隔 10s 轮询一次服务列表并更新。 -
Nacos Server
采用Map
保存实例信息。当配置持久化后,该信息会被保存到数据库中。 -
对于服务健康检查,
Nacos
提供了agent
上报与服务端主动监测两种模式 -
Nacos
支持 CP 和 AP 架构,根据ephemeral
配置决定ephemeral = true
,则为 APephemeral = false
,则为 CP
-
-
Eureka
-
服务提供者启动时,会到
Eureka Server
去注册服务 -
服务消费者会从
Eureka Server
中定时以全量或增量的方式获取服务提供者信息,并缓存到本地 -
各个服务会每隔 30s 向
Eureka Server
发送一次心跳请求,确认当前服务正常运行。若 90s 内Eureka Server
未收到心跳请求,则将对应服务节点剔除。 -
Eureka
遵循可用性原则,即「AP」。Eureka
为「去中心化结构」,没有master
/slave
节点之分。只要还有一个Eureka
节点存活,就仍然可以保证服务可用。但是可能会出现数据不一致的情况,即查到的信息不是最新的。Eureka
节点收到请求后,会在集群节点间进行复制操作,复制到其他节点中。
-
-
Consul
- 服务提供者启动时,会向
Consul Server
发送一个Post
请求,注册当前服务信息 - 服务消费者发起远程调用时,会向
Consul Server
发送一个Get
请求,获取对应服务的全部节点信息 Consul Server
每隔 10s 会向服务提供者发送健康检查请求,确保服务存活,并更新服务节点列表信息。Consul
遵循一致性原则,即「CP」
- 服务提供者启动时,会向
?小T 发现这 4 种组件基本上都可以满足注册中心的需求。在这种场景下,他想要选择一种成本最低、最容易上手的注册中心组件!
- 对于
Zookeeper
,它遵循一致性原则,也就导致其可用性差一些,这对于实际业务场景是致命的。尽管久经考验的Dubbo
框架采用Zookeeper
作为注册中心,但 ?小T 还是更倾向于使用OpenFeign
进行服务调用。 - 对于
Consul
,它底层语言是Go
,更支持容器化场景,而当前项目主语言为Java
,所以 ?小T 就直接将其淘汰啦~ - 对于
Eureka
,它很适合作为注册中心,但是其维护更新频率很低,目前国内使用的人很少,所以也不是很好的选择~
最后,?小T 选择了 Nacos
,选择它的原因也比较简单:
Nacos
底层语言为Java
,天然适配SpringBoot
Nacos
既支持 AP,又支持 CP,更加灵活Nacos
作为SpringCloud Alibaba
的一部分,可以很好地与SpringCloud
进行适配,而项目后续微服务架构是基于SpringCloud
的。Nacos
是国内非常火的注册中心组件,由阿里巴巴开源,开源社区活跃,解决方案多,字面意思就是出了 Bug 能够很快被解决。
总结
基于上述故事,我总结了一个技术选型表格,帮助大家更加直观地学习注册中心。
Zookeeper | Nacos | Eureka | Consul | |
---|---|---|---|---|
CAP 定理 | CP | AP / CP | AP | CP |
通信协议 | TCP | HTTP | HTTP | HTTP |
存储方式 | k-v 存储 | k-v 存储 | k-v 存储 | k-v 存储 |
服务信息变化监听 | Watch 机制 | 长轮询,定时拉取 | 长轮询,定时拉取 | 长轮询,定时拉取 |
是否支持 SpringCloud | 支持 | 支持 | 支持 | 支持 |
是否支持 Dubbo | 支持 | 支持 | 支持 | 支持 |
最后总结
今天,我们仍然是通过 ?小T 停车场的故事,展开了对于注册中心的讲解。
我相信很多小伙伴一定了解或者实践过微服务,但是可能很多时候是「知其然,不知其所以然」,这样很容易形成思维定式,想到注册中心,就会想到微服务,但是并不知道为什么需要使用注册中心。
相信大家看完这篇文章之后,便有了这一问题的答案,也会更加清晰地了解微服务注册中心的「全貌」!
那么今天的微服务内容就到这里啦,大家觉得有用的话请点个赞并持续关注呀,下期再见~