Nacos原理图
Nacos注册中心原理
- 服务实例在启动时注册到服务注册表,并在关闭时注销
- 服务消费者查询服务注册表,获得可用实例
- 服务注册中心需要调用服务实例的健康检查API来验证它是否能够处理请求
- 假设 Nacos Server 已经启动,服务提供者启动时把服务注册到 Nacos 注册中心;
- 服务提供者注册成功后,定时发 http 请求(即心跳)到注册中心,证明自身服务实例可用;
- 如果注册中心长时间没有收到服务提供者的心跳请求,则剔除该实例;
- 服务消费者发现服务支持两种方式,一种是主动请求注册中心获取服务列表(不推荐),一种是订阅注册中心的服务并提交一个 Listener,如果注册中心的服务有变更,由 Listener 来通知服务消费者更新本地服务列表;
- 服务消费者获取服务相关信息进行远程调用。
以Java版本的Nacos客户端为例,服务注册基本流程:
- 服务实例启动将自身注册到Nacos注册中心,随后维持与注册中心的心跳;
- 心跳维持策略为每5秒向Nacos Server发送一次心跳,并携带实例信息(服务名、实例IP、端口等);
- Nacos Server也会向Client主动发起健康检查,支持TCP/Http;
- 15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例;
- 服务消费者通过注册中心获取实例,并发起调用;
其中服务发现支持两种场景:第一,服务消费者直接向注册中心发送获取某服务实例的请求,注册中心返回所有可用实例,但一般不推荐此种方式;第二、服务消费者向注册中心订阅某服务,并提交一个监听器,当注册中心中服务发生变化时,监听器会收到通知,消费者更新本地服务实例列表,以保证所有的服务均可用。
注册
注册中心通过维护serviceHolder去处理每一个服务,为每一个服务通过实例空间。当各个服务启动并注册到注册中心之后就通过心跳的模式保证注册中心可以知晓各个服务的存活状态。如果发现有无心跳的服务那么注册中心就会及时提出失效的服务实例,发送心跳的周期默认是 5 秒,Nacos 服务端会在 15 秒没收到心跳后将实例设置为不健康,在 30 秒没收到心跳时将这个临时实例摘除。
消费
服务注册到注册中心后,服务的消费者就可以向注册中心订阅某个服务,并提交一个监听器,当注册中心中服务发生变更时,监听器会收到通知,这时消费者更新本地的服务实例列表,以保证所有的服务均是可用的。
如果消费者订阅了服务,那么会在本地基于内存维护一个服务信息列表,之后进行服务调用是直接从本地列表获取对应的服务实例进行调用,否则去主从中心获取服务实例。
服务提供者与服务消费者之间是通过feign+ribbon进行配合调用的,feign提供http请求的封装以及调用,ribbon提供负载均衡。负载均衡有很多种实现方式,包括轮询法,随机方法法,对请求ip做hash后取模等等。 Nacos的客户端在获取到服务的完整实例列表后,会在客户端进行负载均衡算法来获取一个可用的实例,默认使用的是随机获取的方式.
Nacos配置中心交互模型是push还是pull
客户端通过长轮询的方式拉取的.
客户端、控制台通过发送Http请求将配置数据注册到服务端,服务端持久化数据到Mysql。
客户端拉取配置数据,并批量设置对dataId的监听发起长轮询请求,如服务端配置项变更立即响应请求,如无数据变更则将请求挂起一段时间,直到达到超时时间。为减少对服务端压力以及保证配置中心可用性,拉取到配置数据客户端会保存一份快照在本地文件中,优先读取。
阿里面试这样问:Nacos配置中心交互模型是push还是pull ?(一)
如果服务端配置与客户端一直没有变化
如果客户端拉取发现客户端与服务端配置是一致的(其实是通过MD5判断的)那么服务端会先拿住这个请求不返回,直到这段时间内配置有变化了才把刚才拿住的请求返回。他的步骤是nacos服务端收到请求后检查配置是否发生变化,如果没有则开启定时任务,延迟29.5s执行。同时把当前客户端的连接请求放入队列。那么此时服务端并没有将结果返回给客户端,当有以下2种情况的时候才触发返回。
- 就是等待29.5s后触发自动检查
- 在29.5s内有配置进行了更改
经过这2种情况才完成这次的pull操作。这种的好处就是保证了客户端的配置能及时变化更新,也减少了轮询给服务端带来的压力。所以之前文章我们说过这个长链接回话超时时间默认是30s。
Nacos注册表如何防止多节点读写并发冲突
写时复制(读写分离)
不采用加锁的设计,可以保证高并发。当要更新实例时,先将内存中的注册表实例复制出来,跟要更新的实例对比,如果不一致,则去更新注册表中的实例。
Eureka、ZooKeeper、Nacos 区别
Eureka 不能支撑大量服务实例,因为 Eureka 的每个节点数据都一致,会产生大量的心跳检查等等导致并发性能低下,ZooKeeper 的频繁上下线通知会导致性能下降,而 Nacos 可以支持大量服务实例又不丢性能,据说服务数量能达到 10 万以上。
Eureka、ZooKeeper、Nacos、Consul 对比
- Eureka 适用于服务实例数量不大的服务注册中心;
- ZooKeeper 相对服务注册中心来说更适用于分布式协调服务;
- Nacos 既适用于大量服务实例的服务注册中心,也可以作为配置中心;
- Consul 更适用于 Service Mesh 架构,使用 Go 语言开发,不方便排查 Bug。
Ribbon-常见的负载均衡算法
- 随机,通过随机选择服务进行执行,一般这种方式使用较少;
- 轮训,负载均衡默认实现方式,请求来之后排队处理;
- 加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
- 地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度;
- 最小链接数,即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上;
Ribbon原理图
Ribbon-饥饿加载
在进行服务调用的时候,如果网络情况不好,第一次调用会超时。Ribbon默认懒加载,初始化负载均衡器,意味着只有在发起调用的时候才会创建客户端。
开启饥饿加载,解决第一次调用慢的问题
# 开启ribbon饥饿加载
ribbon.eager-load.enabled=true
# 指定需要饥饿加载的客户端名称、服务名,多个使用逗号分隔
ribbon.eager-load.clients=server-order
nacos中的ribbon,以及2021版
nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖。
在服务中添加配置,添加 @LoadBalanced 注解。
[五、Spring Cloud Alibaba项目,Ribbon](