Nacos源码之三—接口读取配置

12 篇文章 0 订阅

读取配置流程

读取配置信息流程图

1、入口在ConfigController::getConfig()方法中;

2、获取读锁,如果获取成功,进行下一步,否则返回失败(小于表示正在写入(写锁),等于0表示没有配置数据,因为读锁可以重复获取);

3、根据groupKey获取缓存中的基础信息(isBeta,configType等信息);

4、根据部署方式(是否standalone)、使用的数据库是否是内置数据库 derby,来判断是否读数据库还是读文件;

5、返回数据库中的content信息(如果是查数据库),或者文件流内容。

需要注意的点

1、如果是standalone部署,并且使用的是内置数据库derby,则直接查询数据库中的数据,cache(ConcurrentHashMap);否则,读取nacos文件系统中(nacos/distribution/target/nacos-server- v e r s i o n / n a c o s / d a t a / c o n f i g − d a t a / {version}/nacos/data/config-data/ version/nacos/data/configdata/{GROUP_NAME}/${dataId})的数据。

2、获取配置之前,需要获取读锁

3、通过ConcurrentHashMap缓存配置文件的基础信息,包括:groupKey,md5,lastModifiedTs

// Determines whether to read the data directly
// if use mysql, Reduce database read pressure
// if use raft+derby, Reduce leader read pressure
public static boolean isDirectRead() {
    return EnvUtil.getStandaloneMode() && isEmbeddedStorage();
}

为什么nacos下线了,还可以获取到配置?

因为服务启动的时候,会访问注册中心nacos,把配置更新到环境变量中,可以打开endpoints

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

然后访问:http://localhost:8080/actuator/env,可以查看到配置数据在环境变量中。

值得学习的地方

读写锁的实现

并没有特别高深的内容,使用synchronized关键字修饰获取锁、释放锁的方法。

读锁可以多次获取,通过int类型的status递增实现多次读锁;

只有一个写锁,标记status为-1。

注意:需要手动释放锁。


/**
 * Simplest read-write lock implementation. Requires locking and unlocking must be called in pairs.
 *
 * @author Nacos
 */
public class SimpleReadWriteLock {
    
    /**
     * Try read lock.
     */
    public synchronized boolean tryReadLock() {
        if (isWriteLocked()) {
            return false;
        } else {
            status++;
            return true;
        }
    }
    
    /**
     * Release the read lock.
     */
    public synchronized void releaseReadLock() {
        status--;
    }
    
    /**
     * Try write lock.
     */
    public synchronized boolean tryWriteLock() {
        if (!isFree()) {
            return false;
        } else {
            status = -1;
            return true;
        }
    }
    
    public synchronized void releaseWriteLock() {
        status = 0;
    }
    
    private boolean isWriteLocked() {
        return status < 0;
    }
    
    private boolean isFree() {
        return status == 0;
    }
    
    /**
     * Zero means no lock; Negative Numbers mean write locks; Positive Numbers mean read locks, and the numeric value
     * represents the number of read locks.
     */
    private int status = 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伍六七AI编程

你猜你给我1分我要不要

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值