如何获取配置
整体思路
通过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
非事务操作上,可以任意一个节点来处理
网友评论