2020-12-28

博客园Logo
首页
新闻
博问
专区
闪存
班级

代码改变世界
搜索
注册
登录
返回主页
努力的小雨
活出自己的样子
博客园 首页 新随笔 联系 管理 订阅订阅 随笔- 44 文章- 0 评论- 8
Nacos(一)源码分析Nacos注册示例流程
nacos官方地址:https://nacos.io/zh-cn/

大家可以看一下nacos的中文手册以及官方源码,博主就不带领大家快速入门 了,官方文档中都有而且非常标准,比其他博客写的好多了并且还是实时更新的。

先看一下博主给大家画的流程图,掌握一下大概的基本流程,好理解,博主给大家讲源码:

https://www.processon.com/view/link/5f7e895be0b34d0711f65178

nacos最主要的功能就是服务注册及发现,那它到底是如何实现的呢?博主用的springboot开发的,所以直接就去找nacos的jar包下的spring.factories,这是每个要自动注入的服务jar的必备文件,我们来看一下

里面有很多的自动配置类,我们只看一下NacosServiceRegistryAutoConfiguration,该类主要做的是服务注册的相关事宜,如果大家第一次看源码的话不知道该如何下手,最笨的方法就是一个一个看。总会找到的,最好要找名字看起来就像自己找的,因为这是阿里巴巴开发的,他们是有java开发规范的,要做到见名知意。

复制代码
1 /**
2 * @author xiaojing
3 * @author Mercy
4 */
5 @Configuration(proxyBeanMethods = false)
6 @EnableConfigurationProperties
7 @ConditionalOnNacosDiscoveryEnabled
8 @ConditionalOnProperty(value = “spring.cloud.service-registry.auto-registration.enabled”,
9 matchIfMissing = true)
10 @AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
11 AutoServiceRegistrationAutoConfiguration.class,
12 NacosDiscoveryAutoConfiguration.class })
13 public class NacosServiceRegistryAutoConfiguration {
14
15 @Bean
16 public NacosServiceRegistry nacosServiceRegistry(
17 NacosDiscoveryProperties nacosDiscoveryProperties) {
18 return new NacosServiceRegistry(nacosDiscoveryProperties);
19 }
20
21 @Bean
22 @ConditionalOnBean(AutoServiceRegistrationProperties.class)
23 public NacosRegistration nacosRegistration(
24 NacosDiscoveryProperties nacosDiscoveryProperties,
25 ApplicationContext context) {
26 return new NacosRegistration(nacosDiscoveryProperties, context);
27 }
28
29 @Bean
30 @ConditionalOnBean(AutoServiceRegistrationProperties.class)
31 public NacosAutoServiceRegistration nacosAutoServiceRegistration(
32 NacosServiceRegistry registry,
33 AutoServiceRegistrationProperties autoServiceRegistrationProperties,
34 NacosRegistration registration) {
35 //这里才是自动注入的类,我们需要进去看一下
36 return new NacosAutoServiceRegistration(registry,
37 autoServiceRegistrationProperties, registration);
38 }
39
40 }
复制代码
复制代码
1 public class NacosAutoServiceRegistration
2 extends AbstractAutoServiceRegistration {
3
4 private static final Logger log = LoggerFactory
5 .getLogger(NacosAutoServiceRegistration.class);
6
7 private NacosRegistration registration;
8
9 public NacosAutoServiceRegistration(ServiceRegistry serviceRegistry,
10 AutoServiceRegistrationProperties autoServiceRegistrationProperties,
11 NacosRegistration registration) {
12 super(serviceRegistry, autoServiceRegistrationProperties);
13 this.registration = registration;
14 }
15
16 @Deprecated
17 public void setPort(int port) {
18 getPort().set(port);
19 }
20
21 @Override
22 protected NacosRegistration getRegistration() {
23 if (this.registration.getPort() < 0 && this.getPort().get() > 0) {
24 this.registration.setPort(this.getPort().get());
25 }
26 Assert.isTrue(this.registration.getPort() > 0, “service.port has not been set”);
27 return this.registration;
28 }
29
30 @Override
31 protected NacosRegistration getManagementRegistration() {
32 return null;
33 }
34
35 @Override
36 protected void register() {
37 if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
38 log.debug(“Registration disabled.”);
39 return;
40 }
41 if (this.registration.getPort() < 0) {
42 this.registration.setPort(getPort().get());
43 }
44 super.register();
45 }
46
47 @Override
48 protected void registerManagement() {
49 if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
50 return;
51 }
52 super.registerManagement();
53
54 }
55
56 @Override
57 protected Object getConfiguration() {
58 return this.registration.getNacosDiscoveryProperties();
59 }
60
61 @Override
62 protected boolean isEnabled() {
63 return this.registration.getNacosDiscoveryProperties().isRegisterEnabled();
64 }
65
66 @Override
67 @SuppressWarnings(“deprecation”)
68 protected String getAppName() {
69 String appName = registration.getNacosDiscoveryProperties().getService();
70 return StringUtils.isEmpty(appName) ? super.getAppName() : appName;
71 }
72
73 }
复制代码
看到这里,大家可能有点懵,我应该找那个方法呢?大家可以看一下构造器中,引用了父类,当我们看到父类的时候,发现父类实现了ApplicationListener,这个类大家不陌生,系统会自动执行其onApplicationEvent而正好我们的类实现了这个方法,最后我们发现了应该看register() 方法,大家可以来看看这个方法的实现
复制代码
1 @Override
2 public void register(Registration registration) {
3
4 if (StringUtils.isEmpty(registration.getServiceId())) {
5 log.warn(“No service to register for nacos client…”);
6 return;
7 }
8 //看到这两个参数,大家看过nacos文档就知道这两个参数要干啥用了
9 String serviceId = registration.getServiceId();
10 String group = nacosDiscoveryProperties.getGroup();
11 //要发送的实例对象,具体的属性,大家可以看看这个方法
12 Instance instance = getNacosInstanceFromRegistration(registration);
13
14 try {
15 //走这里,是真正的注册服务
16 namingService.registerInstance(serviceId, group, instance);
17 log.info(“nacos registry, {} {} {}:{} register finished”, group, serviceId,
18 instance.getIp(), instance.getPort());
19 }
20 catch (Exception e) {
21 log.error(“nacos registry, {} register failed…{},”, serviceId,
22 registration.toString(), e);
23 // rethrow a RuntimeException if the registration is failed.
24 // issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
25 rethrowRuntimeException(e);
26 }
27 }
复制代码
复制代码
1 @Override
2 public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
3 //是否是临时的,这个参数默认是临时实例,这个是临时或者是否持久很重要,先记住
4 if (instance.isEphemeral()) {
5 //填写各种心跳信息,毕竟服务需要往nacos发送心跳,nacos才能知道该服务是否还存活
6 BeatInfo beatInfo = new BeatInfo();
7 beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
8 beatInfo.setIp(instance.getIp());
9 beatInfo.setPort(instance.getPort());
10 beatInfo.setCluster(instance.getClusterName());
11 beatInfo.setWeight(instance.getWeight());
12 beatInfo.setMetadata(instance.getMetadata());
13 beatInfo.setScheduled(false);
14 beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());
15 //看一下客服端是如何发送心跳
16 beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
17 }
18 //注册服务
19 serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
20 }
复制代码
复制代码
1 @Override
2 public void run() {
3 if (beatInfo.isStopped()) {
4 return;
5 }
6 long nextTime = beatInfo.getPeriod();
7 try {
8 //会调用nacos服务端的/instance/beat接口
9 JSONObject result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
10 long interval = result.getIntValue(“clientBeatInterval”);
11 boolean lightBeatEnabled = false;
12 if (result.containsKey(CommonParams.LIGHT_BEAT_ENABLED)) {
13 lightBeatEnabled = result.getBooleanValue(CommonParams.LIGHT_BEAT_ENABLED);
14 }
15 BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
16 if (interval > 0) {
17 nextTime = interval;
18 }
19 int code = NamingResponseCode.OK;
20 if (result.containsKey(CommonParams.CODE)) {
21 code = result.getIntValue(CommonParams.CODE);
22 }
23 //如果找不到服务,则进行注册服务
24 if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
25 Instance instance = new Instance();
26 instance.setPort(beatInfo.getPort());
27 instance.setIp(beatInfo.getIp());
28 instance.setWeight(beatInfo.getWeight());
29 instance.setMetadata(beatInfo.getMetadata());
30 instance.setClusterName(beatInfo.getCluster());
31 instance.setServiceName(beatInfo.getServiceName());
32 instance.setInstanceId(instance.getInstanceId());
33 instance.setEphemeral(true);
34 try {
35 //该方法封装好参数后,会调用/instance接口
36 serverProxy.registerService(beatInfo.getServiceName(),
37 NamingUtils.getGroupName(beatInfo.getServiceName()), instance);
38 } catch (Exception ignore) {
39 }
40 }
41 } catch (NacosException ne) {
42 NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
43 JSON.toJSONString(beatInfo), ne.getErrCode(), ne.getErrMsg());
44
45 }
46 //定时线程池不会一直循环进行调用,所以每次执行完之后会继续添加定时任务进行发送心跳
47 executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
48 }
复制代码
  看完发送心跳的方法,我们该看注册服务的方法了:serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);其实就是发送心跳后,找不到服务时调用的/instance接口。

到此,我们的服务就会注册到nacos服务端中,客户端的代码就是如此,还是挺简单的,我们下一篇就会带大家走进服务端的代码。

ps:以上内容,纯属个人见解,有任何问题下方评论!关注博主公众号,你想要的都有,每周不停更哦!原创编写不易,转载请说明出处!
分类: 工作学习
标签: 开发框架
好文要顶 关注我 收藏该文
努力的小雨
关注 - 0
粉丝 - 6
+加关注
0 0
« 上一篇: 项目里出现两个配置类继承WebMvcConfigurationSupport时,为什么只有一个会生效(源码分析)
posted @ 2020-12-26 09:38 努力的小雨 阅读(70) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
写给园友们的一封求助信
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】有你助力,更好为你——博客园用户消费观调查,附带小惊喜!
【推荐】博客园x丝芙兰-圣诞特别活动:圣诞选礼,美力送递
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【福利】AWS携手博客园为开发者送免费套餐+50元京东E卡
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
【推荐】新一代 NoSQL 数据库,Aerospike专区新鲜入驻
相关博文:
· AlibabaNacos学习(四):NacosDocker
· KubernetesNacos
· Nacos简单配置
· Nacos配置中心
· springboot+springcloud+nacos实战
» 更多推荐…
最新 IT 新闻:
· 熬过2020,我的公司还活着
· 一夜之间,两家A股网游上市公司实控人出大事了!
· 苹果造车,到底有没有戏?
· 玩了10小时《赛博朋克2077》 我觉得很失望
· 一文读懂2020年大厂如何调整组织架构
» 更多新闻…
昵称: 努力的小雨
园龄: 2年6个月
粉丝: 6
关注: 0
+加关注
< 2020年12月 >
日 一 二 三 四 五 六
29 30 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2
3 4 5 6 7 8 9
搜索

找找看

谷歌搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签
开发框架(4)
分布式(3)
源码分析(3)
并发(2)
微信接口(2)
小程序(1)
计算机基础(1)
cas(1)
PHP(1)
设计模式(1)
更多
积分与排名
积分 - 33369
排名 - 31377
随笔分类
Java基础(16)
jQuery学习(1)
分布式服务(3)
工作学习(15)
面试解答(4)
设计模式(5)
随笔档案
2020年12月(1)
2020年9月(2)
2020年8月(2)
2020年7月(3)
2019年10月(3)
2019年9月(3)
2019年7月(1)
2019年4月(1)
2019年3月(1)
2019年2月(2)
2018年10月(1)
2018年9月(4)
2018年7月(4)
2018年6月(16)
相册
公众号(1)
最新评论

  1. Re:源码分析springboot自定义jackson序列化,默认null值个性化处理返回值
    按我的理解说一下,你看对不对: 初始场景是:A-1.0.0调用B-1.0.0,B接口输入数据类型是X(包含a、b、c三个字段),返回数据类型是Y(包括x、y、z三个字段)。 第一次升级:B升级到1.1…
    –小陆
  2. Re:源码分析springboot自定义jackson序列化,默认null值个性化处理返回值
    @小陆 大神可否举个例子说明一下,评论有点抽象,源码中的JSON反序列化是对每一个字段的类型都会进行解析,无论开发者如何修改返回值,只要为空的返回值类型是我需要解析的,我都会按照与前端约定的格式进行序…
    –努力的小雨
  3. Re:源码分析springboot自定义jackson序列化,默认null值个性化处理返回值
    最近项目要实现一种需求,对于后端返回给前端的json格式的一种规范,不允许缺少字段和字段值都为null JSON反序列化一般要求忽略不一致的属性,目的是尽量保持接口兼容性,防止出现破坏性升级。 如果要…
    –小陆
  4. Re:扫码点餐数据上报_渠道商-微信接口
    扫码点餐数据上报API_服务商_v1.3 请问有吗?
    –我们的家乡
  5. Re:扫码点餐数据上报_渠道商-微信接口
    有两点
    1.通过接口请求回来的序列号 并不是在点餐上报时的序列号
    2.点餐上报的时候 加签是需要用证书来加的
    –蜗牛-慢爬
    阅读排行榜
  6. Vector,ArrayList,LinkedList有何区别?(7549)
  7. 微信小微商户直连接口详解(5699)
  8. 虚拟机使用桥接模式网络配置(4642)
  9. 对大数据的批量导入MySQL数据库(3889)
  10. daterangepicker的个性化使用技巧(1903)
    评论排行榜
  11. 扫码点餐数据上报_渠道商-微信接口(5)
  12. 源码分析springboot自定义jackson序列化,默认null值个性化处理返回值(3)
    推荐排行榜
  13. Springboot拦截器使用及其底层源码剖析(2)
  14. 设计模式之过滤器模式(1)
  15. 微信小微商户直连接口详解(1)
  16. 虚拟机使用桥接模式网络配置(1)
    Copyright © 2020 努力的小雨
    Powered by .NET 5.0.1-servicing.20575.16 on Kubernetes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值