今天,我们从源码的角度出发,看看nacos是如果进行服务注册,服务调用,负载均衡,心跳检测等功能。 首先大家我们去github上拉取代码,https://github.com/alibaba/nacos ,打开后我们先从注册实例作为入口开始看,注册实例的接口在API模块:
服务注册
点进去发现里面有不同的方法,我们以第一个为例,
他是先初始化一个Instance对象,赋值后调用registerInstance()方法,通过clientProxy.registerService()去注册实例,继续往下追踪
这个NamingClientProxy()接口有多个实现类(根据实现类的名称我们看到他这里用了策略模式来处理HTTP还是RPC请求)我们先看HTTP实现类是如果处理的:
心跳检测发送
关注下我圈起来的地方,这里就是心跳机制的开始喽,他先创建一个BeanInfo对象,然后交给beatReactor.addBeanInfo()这个方法。这个beatReactor看起来像个容器,那我们就去看一下他是怎么处理的。
这个类有个定时任务线程池,看到这里,我们大概就猜得出他的心跳检测机制应该是通过定时任务线程池去处理的。然后我们再看他的addBeatInfo()方法做了什么?
果然不出所料,先创建BeatTask对象然后交给定时任务线程池去定时处理这个实例信息,但是他的定时任务应该只执行一次呀,他是怎么一直不断的检测的呢,我们进BeatTask这个内部类看看他是怎么循环处理的:
通过这段代码我们可以清楚的看到他是通过在BeanTask的run()方法重复执行定时任务达到一直循环检测的需求。 然后我们返回继续注册实例
封装请求参数,调用API
最后发送注册实例的HTTP请求,一个注册实例的完整链路就走完啦。
负载均衡
我们看获取实例的时候nacos是怎么处理的
先尝试从serviceInfoHolder获取服务信息如果没获取到,则通过clientProxy调用API去获取所有实例列表
但是我只要一个,他应该返回我哪一个呢?注意这个Balancer.RandomByWeight.selectHost(serviceInfo);就是负载均衡的关键,
最后从ref里面通过随机数获取一个实例返回。 当然他的负载均衡有好几种策略。有轮询,weight权重,ip_hash,fair,等。大家有兴趣的可以自己去翻一翻都是怎么实现的。
最后如果有理解的不对的地方,欢迎大家指正纠正,一起进步。希望今天的文章对小伙伴们有帮助。