当前位置:网站首页>Nacos手摸手教学【二】Nacos注册中心
Nacos手摸手教学【二】Nacos注册中心
2022-08-04 11:47:00 【LoneWalker、】
前言
上一篇我们说到Nacos作为动态配置中心,那么这篇来聊聊Nacos作为服务注册中心。注册中心其实就类似于企查查这种平台,把公司信息汇合到这个平台方便别人使用。我们把服务注册到Nacos也就是为了让别人发现我们的服务并且使用它。

本文基于Cloud Alibaba 2021.0.1.0 + Springboot 2.6.3
搭建服务
首先还是以单机模式启动nacos-serve
startup.cmd -m standalone
服务提供者与服务消费者的pom中均添加以下场景启动器
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.0.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.2</version>
</dependency>我这里基于【Nacos手摸手教学一】来做的,服务提供者的bootstrap.yml 注意修改namespace、ip
spring:
cloud:
nacos:
config:
server-addr: ip:8848
file-extension: yaml
namespace: 434e7801-0b5d-4fd2-b96a-acbac849fd84
discovery:
server-addr: ip:8848
application:
name: provider-serve
profiles:
active: dev服务消费者的配置文件一样的,不一样的也就是服务名consumer-serve
接下来我们启动两个服务,回到nacos控制台

原理
服务确实注册到Nacos了,表面来看我们相当于登记了姓名,那么如果我把某个服务停了,nacos又是如何知道该服务还能不能正常使用的呢?我们不仅要知其然,也要知其所以然。
大致流程:每个服务都会有一个nacos client,它用来和nacos server打交道,用来具体的服务注册、查询等操作,服务提供者在启动的时候会向nacos server注册自己,服务消费者在启动的时候订阅nacos server上的服务提供者。

NacosNamingService 中的 registerInstance 方法用于向Nacos注册实例,Nacos 中的实例分为临时和永久2种类型,注册前先判断实例是否是临时实例(默认都是临时实例),如果是Instance是临时实例,则创建一个 BeatTask 心跳线程定期调用 HTTP PUT /instance/beat 向 Nacos 服务器发送心跳,然后调用 HTTP POST /instance 向 Nacos 服务器注册实例。

BeatTask 线程通过 HTTP PUT /instance/beat 向 Nacos 发送心跳请求,如果当前实例在服务器上不存在,则重新注册实例,否则等待执行下一次心跳。以下源码来自BeatReactor类
@Override
public void run() {
if (beatInfo.isStopped()) {
return;
}
//下一次心跳时间
long nextTime = beatInfo.getPeriod();
try {
//发送心跳
JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
long interval = result.get("clientBeatInterval").asLong();
boolean lightBeatEnabled = false;
if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
}
BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
//使用服务器返回的心跳时间
if (interval > 0) {
nextTime = interval;
}
int code = NamingResponseCode.OK;
if (result.has(CommonParams.CODE)) {
code = result.get(CommonParams.CODE).asInt();
}
//服务器返回实例不存在,重新注册实例
if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
Instance instance = new Instance();
instance.setPort(beatInfo.getPort());
instance.setIp(beatInfo.getIp());
instance.setWeight(beatInfo.getWeight());
instance.setMetadata(beatInfo.getMetadata());
instance.setClusterName(beatInfo.getCluster());
instance.setServiceName(beatInfo.getServiceName());
instance.setInstanceId(instance.getInstanceId());
instance.setEphemeral(true);
try {
//重新注册实例
serverProxy.registerService(beatInfo.getServiceName(),
NamingUtils.getGroupName(beatInfo.getServiceName()), instance);
} catch (Exception ignore) {
}
}
} catch (NacosException ex) {
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
JacksonUtils.toJson(beatInfo), ex.getErrCode(), ex.getErrMsg());
}
//开启下一次心跳
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
}服务端也会为每个 Service 启动一个 ClientBeatCheckTask 线程用于检测该 Service 下所有的实例的健康状态,如果实例的 lastBeat 最后心跳时间超过了心跳超时时间(默认15秒),则设置 healthy 健康状态为 false,并通过 UDP 向客户端 push 最新的数据,如果 lastBeat 超过30秒,表示此实例已不可用,通过调用 HTTP DELETE /instance 从实例列表中删除该实例。
边栏推荐
- 入门MySql表的增删查改
- 终于有人把分布式机器学习讲明白了
- Transferring Rich Feature Hierarchies for Robust
- UMA&港理工&阿里提出SP-ViT,为视觉Transformer学习2D空间先验知识!
- Leetcode刷题——543. 二叉树的直径、617. 合并二叉树(递归解决)
- UMA & Hong Kong Polytechnic & Ali propose SP-ViT to learn 2D space prior knowledge for visual Transformer!
- 『快速入门electron』之实现窗口拖拽
- ECCV 2022 | 通往数据高效的Transformer目标检测器
- 喂,你知道节流是什么吗?
- 数据库表列类型;DML_添加数据;DDL_修改,删除数据库表
猜你喜欢

深度学习------pytorch实现划拳模型训练

Flutter使用 json_serializable 解析 JSON 最佳方案

ECCV 2022 | Towards Data Efficient Transformer Object Detectors

Xilinx VIVADO 中 DDR3(Naive)的使用(3)仿真测试

JS逆向字体反爬,某供应商平台反爬实践

COVID-CT新冠肺炎检测(DenseNet网络)

入门MySql表的增删查改

深度学习------戴口罩和不戴口罩

Leetcode刷题——二叉搜索树相关题目(98. 验证二叉搜索树、235. 二叉搜索树的最近公共祖先、1038. 从二叉搜索树到更大和树、538. 把二叉搜索树转换为累加树)

MySql数据库入门的基本操作
随机推荐
asp.net解决大文件断点续传
什么是 DevOps?看这一篇就够了!
子查询
#夏日挑战赛#OpenHarmony 给你的输入法加点彩—星球崛起
POJ2367Genealogical tree题解
【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库
Flutter强大的下拉筛选菜单gzx_dropdown_menu
光盘刻录步骤
【全网首发】Redis系列5:深入分析Cluster 集群模式
如何用一条命令将网页转成电脑 App
Leetcode刷题——二叉搜索树相关题目(98. 验证二叉搜索树、235. 二叉搜索树的最近公共祖先、1038. 从二叉搜索树到更大和树、538. 把二叉搜索树转换为累加树)
【飞控开发高级教程7】疯壳·开源编队无人机-编队飞行
【黄啊码】MySQL入门—1、SQL 的执行流程
MTBF是什么意思?交换机做MTBF有什么要求?MTTF、MTBF和MTTR的区别是什么?
拦截器,文件流,下载文件?
剑指offer专项突击版第19天
十一、网络规划设计
你值得拥有的登录注册页面(附赠源码)
POJ1094Sorting It All Out题解
Hands-on Deep Learning_LeNet