nacos源码分析

如何获取配置

整体思路

通过http请求从nacos中获取配置,并放在本地文件中。

流程图

dgm5eed64950281.png

配置如何存储

整体思路

1 通过http的post请求,调用ConfigController#publishConfig的方法


image.png

2 保存到derby数据库中并触发ConfigDataChangeEvent改变的事件通知。

流程图

配置通知

整体思路

客户端

通过定时调度来异步分批次执行
1 根据dataId和group向服务端发送/v1/cs/configs/listener的post请求来获取值改变的dataId和group列表
2 根据dataId和group向服务端发送/v1/cs/configs请求获取内容值
3 检查旧的md5和新的md5是否相等,若不相等则触发监听。

this.md5 = getMd5String(this.content);
服务端

1 比较客户端传过来的md5和服务端自己的md5是否相等,若不相等则直接把改变的dataId和group返回给客户端;若相等,则延迟超时时间-500ms发送完成标记,dataId为空(ScheduledExecutorService)
2 通过发布-订阅机制,当dataId发生修改时,不管内容是否相同,都会发送给客户端。
3 触发事件:当dataId的内容发生修改时触发
当dataId的内容发生修改时触发事件,ConfigDataChangeEvent事件,发送/dataChange的请求,在更新缓存中的md5,若发生改变则触发LocalDataChangeEvent事件

public static void updateMd5(String groupKey, String md5, long lastModifiedTs) {
    CacheItem cache = makeSure(groupKey);
    if (cache.md5 == null || !cache.md5.equals(md5)) {
        cache.md5 = md5;
        cache.lastModifiedTs = lastModifiedTs;
        EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey));
    }
}   

问题思考

为什么超时时间需要减去-500ms

为了避免客户单超时,提前一段时间返回

int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
long timeout = Math.max(10000, Long.parseLong(str) - delayTime);
长轮询

客户端发起一个请求到服务端,服务端收到客户端的请求后,并不会立刻响应给客户端,而是先把这个请求hold住,然后服务端会在hold住的这段时间检查数据是否有更新,如果有,则响应给客户端,如果一直没有数据变更,则达到一定的时间(长轮训时间间隔)才返回。

流程图

集群选举

Raft算法

raft是分布式一致性的实现。

三种角色

leader:负责接收客户端请求并处理事务请求
Candidate:用于leader选举的角色
Follower:负责接收leader和Candidate的请求,可以处理非事务请求。

选举算法

1 触发选举:当服务启动时,所有节点都是Follower节点或者leader节点挂了,在一段时间内没有接收到leader心跳后,会把follower转变为Candidate,开始选举。
2 选举周期+1,先选举自己当leader,并且发送给其他节点,等待其他节点的回应。
若收到过半请求,则成为leader。
若被告知有节点成为leader,则成为follower
若一段时间内,没有收到过半请求,则重新选举。
约束条件在任一term中,单个节点最多只能投一票
3 选举的几种情况
第一种情况,赢得选举之后,leader会给所有节点发送消息,避免其他节点触发新的选举
第二种情况,比如有三个节点A B C。A B同时发起选举,而A的选举消息先到达C,C给A投了一票,当B的消息到达C时,已经不能满足上面提到的第一个约束,即C不会给B投票,而A和B显然都不会给对方投票。A胜出之后,会给B,C发心跳消息,节点B发现节点A的term不低于自己的term,知道有已经有Leader了,于是转换成follower
第三种情况, 没有任何节点获得majority投票,可能是平票的情况。加入总共有四个节点(A/B/C/D),Node C、Node D同时成为了candidate,但Node A投了NodeD一票,NodeB投 了Node C一票,这就出现了平票 split vote的情况。这个时候大家都在等啊等,直到超时后重新发起选举。如果出现平票的情况,那么就延长了系统不可用的时间,因此raft引入了randomized election timeouts来尽量避免平票情况

数据的处理

对于事务操作,请求会转发给leader
非事务操作上,可以任意一个节点来处理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。