转自:https://www.jianshu.com/p/61608ff86344

Nacos 另一个非常重要的特性就是服务注册与发现,说到服务的注册与发现相信大家应该都不陌生,在微服务盛行的今天,服务是非常重要的,而在 Nacos 中服务更被称为他的一等公民。

Nacos 支持几乎所有主流类型的 “服务” 的发现、配置和管理。

了解过 Dubbo 的同学,应该对 Dubbo 的架构非常熟悉,最经典的一张架构图如下所示:

 

图中的6个步骤的含义解释如下:

0、服务容器负责启动,加载,运行服务提供者。
1、服务提供者在启动时,向注册中心注册自己提供的服务。
2、服务消费者在启动时,向注册中心订阅自己所需的服务。
3、注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4、服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5、服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

其中图中最上方的 Registry 就是注册中心,负责服务的注册与发现。Dubbo 有自己的 Registry 实现,而 Nacos 则是另一种 Registry 的实现。

现在我们来了解下 Nacos 的服务注册与发现,首先在本地将 Nacos 服务端启动起来,具体怎么操作这里不在赘述,不清楚的同学可以参考我的其他文章。

模拟服务注册

我们模拟将同一个服务的两个实例注册到 Nacos 中,代码如下图所示:

 

通过 NamingService 接口的 registerInstance 方法就可以将服务进行注册了,该方法有很多重载的方法,这里我们选择一个简单的来调用就好了。

注册完成后,通过调用 getAllInstances 方法,立即获取所有可用的实例,然后让主线程等待,打印如下:

 

从打印结果中可以发现 naming 客户端成功获取到了两个实例。

模拟服务发现

服务注册之后,服务的消费者就可以向注册中心订阅自己所需要的服务了,注册中心会将所有服务的实例“推送”给消费者,这里我在推送上打了引号,原因是实际上获取服务是客户端主动轮询的,跟客户端获取配置中心的配置项的原理一样。这里不进行具体的描述,有兴趣的可以跟一下代码就知道了。

现在我创建一个服务消费者,然后向注册中心订阅一个服务,当接收到注册中心返回的服务列表之后,执行5次 select 服务实例的操作,相当于进行一个模拟的服务请求,具体的代码如下图所示:

service-consumer.jpg

其中的 printInstances 方法主要是打印出所有服务的实例,为了节省篇幅就不写出来了,将 ServiceConsumer 类启动之后,打印出如下的日志:

 
service-consumer-effect.jpg

消费者每次获取一个健康的实例进行调用,接下来我就来分析下整个服务注册与发现的过程和大致的设计原理和思路。

服务如何注册

服务注册最重要的就是将服务注册到哪里,在注册中心服务端,肯定有一个用来管理服务的容器,他保存着所有服务的实例。

我们暂时不需要知道该容器具体的实现细节,只需要知道有这样一个概念。

 

nacos-registry-princple-1.jpg
 

nacos-registry-princple-2.jpg
 

nacos-registry-princple-3.jpg
 

nacos-registry-princple-4.jpg

服务如何发现

服务注册到注册中心后,服务的消费者就可以进行服务发现的流程了,消费者可以直接向注册中心发送获取某个服务实例的请求,这种情况下注册中心将返回所有可用的服务实例给消费者,但是一般不推荐这种情况。另一种方法就是服务的消费者向注册中心订阅某个服务,并提交一个监听器,当注册中心中服务发生变更时,监听器会收到通知,这时消费者更新本地的服务实例列表,以保证所有的服务均是可用的。

 

nacos-registry-princple-5.jpg
 

nacos-registry-princple-6.jpg

负载均衡

负载均衡有很多中实现方式,包括轮询法,随机方法法,对请求ip做hash后取模等等,从负载的维度考虑又分为:服务端负载均衡和客户端负载均衡。

Nacos 的客户端在获取到服务的完整实例列表后,会在客户端进行负载均衡算法来获取一个可用的实例,模式使用的是随机获取的方式。

 

nacos-registry-princple-7.jpg

Nacos 服务注册与订阅的完整流程

Nacos 客户端进行服务注册有两个部分组成,一个是将服务信息注册到服务端,另一个是像服务端发送心跳包,这两个操作都是通过 NamingProxy 和服务端进行数据交互的。

Nacos 客户端进行服务订阅时也有两部分组成,一个是不断从服务端查询可用服务实例的定时任务,另一个是不断从已变服务队列中取出服务并通知 EventListener 持有者的定时任务。

 

nacos-service-register-found.png

官方提供的demo具有一定的迷惑性,不过这能迫使你去了解事物的本质。

你如果直接官方的demo,你会发现如下有趣的情况:

1、第一次注册了两个实例,获取实例时返回的是2个

2、然后解除注册其中的一个实例,再次获取实例时返回的还是2个

3、订阅服务的监听器将会收到两次 onEvent 回调,第一次是2个实例,第二次是1个实例

按照正常的情况,注册了两个实例,然后解除注册了一个只会,再次获取实例应该返回1个实例才对,但是返回了2个。

深入了解下源码就能知道原因:

客户端将获取到的服务实例保存在一个 map 中,而该 map 中的内容是由调度任务定时去更新的,存在一定的延时。

用Nacos做微服务架构里的服务注册与发现中心的更多相关文章

  1. Chris Richardson微服务翻译:微服务架构中的服务发现

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...

  2. 8.rabbitmq RPC模拟微服务架构中的服务调用

    标题 : 8.rabbitmq RPC模拟微服务架构中的服务调用 目录 : RabbitMQ 序号 : 8 { var connectionFactory = new ConnectionFactor ...

  3. SpringCloud服务注册与发现中心-Eureka

    1.服务注册与发现的好处: 假设没有这个东西,那么如果存在a,b,c三个同样的服务: 而现在有一个u服务需要用到a或b或c提供的接口,那么u里面肯定是需要配置这三个服务的地址,然后调用的时候还有问题就 ...

  4. 微服务架构 - 解决Docker-Compose服务编排启动顺序问题

    基于Docker Compose进行服务编排时,一定碰到服务启动顺序的问题,例如:B服务启动之前,A服务要已经启动并且可以正常对外服务. 这个启动顺序的问题,Docker Compose本身它是无法解 ...

  5. 微服务通信之feign的注册、发现过程

    前言 feign 是目前微服务间通信的主流方式,是springCloud中一个非常重要的组件.他涉及到了负载均衡.限流等组件.真正意义上掌握了feign可以说就掌握了微服务. 一.feign的使用 f ...

  6. spring cloud微服务架构 服务提供者和服务消费者

    服务提供者和服务消费者 下面这张表格,简单描述了服务提供者/消费者是什么:   | 名词 | 概念 | | ----- | ----------------------- | | 服务提供者 | 服务 ...

  7. springcloud微服务架构搭建:服务调用

    spring-cloud调用服务有两种方式,一种是Ribbon+RestTemplate, 另外一种是Feign. Ribbon是一个基于HTTP和TCP客户端的负载均衡器,类似nginx反向代理,可 ...

  8. Spring Cloud云服务架构 - commonservice-config配置服务搭建

    1. 介绍 Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持.使用Config Server,您可以在所有环境中管理应用程序的外部属性.客户端和服务器上的概念映射与 ...

  9. SpringCloud用Zookeeper做服务注册与发现中心代码实现

    一:Zookeeper用的是3.5.5版本,SpringBoot用的是2.1.6版本,SpringCloud用的是Greenwich.SR2版本,JDK用的是1.8: 服务提供者product-ser ...

随机推荐

  1. 【转】Hive 修改 table、column

    表 1.重命名表重命名表的语句如下: ALTER TABLE table_name RENAME TO new_table_name 2.修改表属性: ALTER TABLE table_name S ...

  2. Struts动态结果集,了解一些就好

    Struts动态结果集dynamic_result    在struts配置文件中${成员变量}(不是EL表达式,是ognl表达式)符号可以从value stack(即值栈)中取值,可以在action ...

  3. 腾讯云CENTOS7安装MSSQL2017

    腾讯云CENTOS7安装MSSQL2017 mkdir -p /opt/sqlserver2017cd /opt/sqlserver2017/ 下载离线包:wget https://packages. ...

  4. arcpy模块下的并行计算与大规模数据处理

    一个多星期的时间,忍着胃痛一直在做GIS 540: Spatial Programming的课程项目,导致其他方面均毫无进展,可惜可惜.在这个过程当中临时抱佛脚学习了很多Python相关的其他内容,并 ...

  5. 在Eclipse IDE进行Struts开发时提示错误:java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.FilterDispatcher的解决办法

    If you have... included all necessary jars Configured build path correctly added them all in deploym ...

  6. linux设备树编译器DTC【转】

    本文转载自:https://blog.csdn.net/chenmiaowu88/article/details/54342823 参考文件: \kernel\Documentation\device ...

  7. MQTT基础概念介绍

    https://blog.csdn.net/pipinet123/article/details/60866901 源博客地址:http://blog.csdn.net/pipinet123 MQTT ...

  8. Linux 操作系统 & High Tech

    分享10大白帽黑客专用的 Linux 操作系统 - 51CTO.COMhttp://os.51cto.com/art/201905/597156.htm Ubuntu 创始人谈论为什么 Linux 在 ...

  9. layui表格工具条,如何动态控制按钮的展示?

    <script type="text/html" id="toolTpl"> {{# if(d.agrgrtsts == 'A'){ }} < ...

  10. 峰回路转的提权08r2服务器

    事前日下这个站的时候说实话,略微的蛋疼.其过程就不写了,就讲讲提权吧.可能图片有点暗.看看我写这篇文章的时候就知道了. 这个学校我好多同学在里面读书,就萌生了.日下这个站的想法. 拿到shell,理所 ...