美文网首页
nacos源码分析

nacos源码分析

作者: 剑道_7ffc | 来源:发表于2020-06-24 08:22 被阅读0次

    如何获取配置

    整体思路

    通过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
    非事务操作上,可以任意一个节点来处理

    相关文章

      网友评论

          本文标题:nacos源码分析

          本文链接:https://www.haomeiwen.com/subject/mebmxktx.html