15、Nacos 源码分析总结

本篇是对Nacos源码分析的一个总结。也是对整个Nacos源码分析系列的一个总结反思。

Nacos源码分析的第一篇,就开门见山的从一个客户端的Example开始分析。

分析源码的第一步是需要先找到源码的入口

在分析的过程中,我们以抽丝剥茧的方式,一步步的去跟踪,因为有时候看似调用了一个简单函数,其实内部逻辑并不简单。

我们很容易被方法名屏蔽双眼。所以在分析源码过程中千万不要自以为然。当然,我们可以先简单的过一遍流程。了解一下这个方法大概做了什么,再去深入细节,不然也容易被迷晕在细节之中,久久转不出来。

跟着方法分析后,但是java是支持多态的,很多时候一个接口有很多实现,要尝试使用代码分析法和断点调试法找到真实所调用的方法逻辑。

分析源码也是有一定的技巧的,我们要善用IDE强大的查找和Debug功能,这样能够帮助我们快速查找调用者和被调用者。

而在源码中,往往会使用大量的设计模式。如果我们不熟悉设计模式,往往会很难找到真实的处理逻辑和作者的意图,并影响们对整体框架逻辑的理解。

分析源码的过程必须要熟悉常用的设计模式,否则分析将会是个很痛苦的过程。

在第一篇分析完Rpc的调用后,就完成了客户端部分的代码分析。因为我们分析代码肯定是阶段性的分析,不可能一次性的分析完所有代码,我们要自己给自己设立很多小目标,一个阶段一个阶段的去完成我们的小目标,最终达到大目标。

接下来后续5篇开始分析服务端的代码。

作为服务端的源码,往往是比客户端的代码要复杂的多的。因为服务端会将接口的内容高度抽象,尽量方便于客户端的使用。而在源码部分,因为没有一些基础设施的,基础框架的集成,比如SpringMybatisHibernate。其往往需要自行的去维护一些参数和变量。所以我们常常在debug的时候看到调用栈很深,而且往往一个变量中有很多属性,这都是因为他需要自己去维护这些参数,这些属性值,只有对象中有了这些对象和参数值,在需要用到的时候才能更方便。我们在分析过程中也会看到很多的构造函数初始化了一些变量,在某些特定类中,放着很多个Map,List等容器对象,都是为了存储我们需要使用的类和变量。

想象一下,源码没有平时我们使用的数据库,缓存,消息队列,那怎么进行数据保存,怎么进行消息通知。当我们的服务节点是单机应用还好,可以用java.util包中的方法和数据结构,如果是多线程,并发的情况,其也提供了相关的处理类。但是可能也需要一些改造,自己造一些适用的轮子。印象比较深的是在NacosNotifyCenterSimpleReadWriteLock,自定义发布-订阅模式,自定义一个简单的读写锁。这些都是自己造适用轮子的例子。

当单机应用考虑到集群化,分布式应用的时候,这个就更加复杂了。可能需要引入分布式协调的中间件。假如不引用,就得自己花费额外的大量的工作量去处理数据的一致性,网络分区,应用可用性等一系列内容。这其中的复杂度可能直接提升好几个数量级,没有大量经验或者大量实践,一切看似非常完美的代码都会变得弱不禁风,经不起岁月的考验。

如果你是第一次或者刚开始分析源码,千万不要忽略了线程栈和重要的变量。当然这些东西也不是平白无故而产生的,一定是一层层,一步步调用得来的。而要能将这些变量组装好,完美的运行,需要大量的积累和高度的设计,否则很容易在工程项目越来越大的情况下出现架构腐蚀,架构崩坏。

那按上面写的,服务端那么复杂,而我们大部分时间都是拿到服务端的API调用即可,还有必要去研究吗?

答案显而易见,当然要去研究。毕竟我们都是有理想的程序员,怎么能只甘愿做一个API Boy。如果我们仅仅只是使用API,这样服务端就变成了黑盒,如果服务端没有报错还好,报错了的话,我们应该如何处理呢。分析服务端的源码,可以让我们更加清楚和明白的去使用API,或者说知道何时在什么地方调用合适的API。另外,服务端的代码之所以复杂,是因为其考虑了性能,可用性,安全性,并发性等各种非功能性的一些内容。有些看似绕来绕去的逻辑是为了能够更好的复用一些代码亦或者方便扩展其原有的逻辑。这也是我们在分析过程中需要去学习那些优秀开发者的内容。在分析过程中学习优秀的写法,学习优秀的设计。

当我们分析到一些代码无法理解的时候,我们也可以采用反推导的方式,从响应的结果为导向,分析作者设计的原因。

在服务端的源码分析的时候,我们也要注意我们的主线在哪里。因为服务端有很多逻辑或者一些旁路逻辑,是为了代码的健壮性而考虑的。分析过程要抓大头,先把主线弄清楚。如果对某部分代码和细节感兴趣,再抽时间去分析内部的细节部分,这样可以做到事半功倍,并且让自己更有信心的分析下去。

Nacos注册服务端的分析中,如果能够理解订阅-发布异步线程处理的话,就明白了其分析的主线,再从各个事件去分析逻辑就不难了。

分析完服务注册部分后,又继续分析了Nacos的配置服务源码。

配置服务的源码分析也是从客户端开始。分析客户端的时候,了解到了一些配置的"后门"。比如说在指定文件夹或者指定配置,就可以实现读取本地的配置文件,方便在一些特殊情况的处理。如果没有这些"后门",可能会在极端情况下,无法做到配置更新。这也告诉我们平时多留条路,虽然逻辑是复杂了一些,代码复杂了一些,但是关键时刻可能会救了自己。

这种往往是踩过了一些坑后,才能知道为啥要这么做

接着又分析了配置服务的服务端,其核心思想依然是订阅-发布。当配置信息变动后,通知对应的订阅者,触发订阅者的更新逻辑。而这其中又掺杂了大量的异步线程池的异步化的处理。

其实分析过程是一个被动接受的过程,更多是去接受作者的思想和思路,难的是自己去创造,并且保证代码能够按照自己的逻辑运行,当其进行异步化之后,调试的复杂性和不确定性将会成倍的增加。

后续又应了一个粉丝的要求,自己研究了下NacosDistro协议。其实在分析Distro协议的时候,我发现这其实和之前分析的一些源码串联起来的。如果没有之前的一些积累,分析起来肯定会费劲很多,因为Distro协议是集成了很多基础功能的,比如说NotifyCenterTaskEngine,RpcProxy等内容。如果在分析过程中还一味的去追究每个组件的细节与功能,则很容易迷失在各个细节之中。但是有了之前的经验,在心中有了一定的积累,就可以很快定位到具体的逻辑,快速的理解其主线逻辑脉络。这样也从另一个角度说明了,我们需要一步一个脚印,慢慢积累我们所学的知识,虽然可能当时不一定清楚会怎么用上或者不知道用在哪里,但是如果一直积累下去,等需要用的时候,你就能信手拈来,将点串成线,再由线转换成面,进行不断的思考和扩展,最终形成自己的一套知识体系。

经过这一系列的源码分析,我也只是窥探到了Nacos的冰山一角,还有很多知识点和知识面没有涉及。希望能帮助大家打开思路,自行的去分析去思考,形成自身独到的见解。甚至大家可以去参与Nacos的建设,优化Nacos的功能,共建Nacos社区。

最后感谢大家在Nacos源码分析专栏的一路陪伴。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nacos 是一个开源的分布式配置中心和服务发现框架,它提供了服务注册、发现、配置管理等功能。下面是对 Nacos 源码的简要分析: 1. 项目结构:Nacos 代码库主要包括 core 模块、config 模块、discovery 模块等。core 模块提供了核心的数据结构和服务注册与发现的功能,config 模块实现了配置管理相关的功能,discovery 模块实现了服务发现的功能。 2. 注册与发现:Nacos 使用了基于 Raft 算法的一致性协议来实现注册与发现功能。核心模块中的 ServerListManager 负责管理服务列表的变更和更新,InstanceEventProcessor 负责处理服务实例事件。服务注册和发现的过程涉及到数据存储和同步,涉及到的类有 LocalServerData、MetadataManager、SnapshotManager 等。 3. 配置管理:Nacos 的配置管理功能由 config 模块实现。核心类是 ConfigServiceImpl,它负责处理配置的读写和监听。在配置写入时,会通过 ConfigChangePublisher 将变更发布给订阅者。ConfigChangeListeners 负责处理配置变更事件。 4. 数据存储:Nacos 的数据存储使用了内置的嵌入式数据库 Derby。Derby 提供了基于文件的持久化存储,用于存储配置数据、注册数据等。 5. 服务路由:Nacos 通过实现了 LoadBalancer 接口来实现服务路由的功能。LoadBalancer 负责选择可用的服务实例,实现了负载均衡的策略。 这只是对 Nacos 源码的简要分析Nacos源码结构比较复杂,涉及到的技术栈也比较丰富。如果你对具体的实现细节有更多的疑问,可以参考 Nacos 的官方文档或者深入阅读源码

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值