暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Apollo源码解析-RemoteConfigRepository

鲁班同学 2019-10-18
1026

RemoteConfigRepository:远程Repository,实现从ConfigService拉取配置,并缓存,支持实时,定时

  

  public RemoteConfigRepository(String namespace) {
m_namespace = namespace;
m_configCache = new AtomicReference<>();
m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
m_httpUtil = ApolloInjector.getInstance(HttpUtil.class);
m_serviceLocator = ApolloInjector.getInstance(ConfigServiceLocator.class);
remoteConfigLongPollService = ApolloInjector.getInstance(RemoteConfigLongPollService.class);
m_longPollServiceDto = new AtomicReference<>();
m_remoteMessages = new AtomicReference<>();
m_loadConfigRateLimiter = RateLimiter.create(m_configUtil.getLoadConfigQPS());
m_configNeedForceRefresh = new AtomicBoolean(true);
m_loadConfigFailSchedulePolicy = new ExponentialSchedulePolicy(m_configUtil.getOnErrorRetryInterval(),
m_configUtil.getOnErrorRetryInterval() * 8);
gson = new Gson();
//尝试同步配置
this.trySync();
// 初始化定时刷新配置定时
this.schedulePeriodicRefresh();
// 注册自己到RemoteConfigLongPullService,实现配置更新实时通知
this.scheduleLongPollingRefresh();
}


解释: 构造函数,初次尝试同步配置,初始化刷新配置定时任务,之后注册自己到RemoteConfigLongPollService


进入trySync()

/**
* 尝试同步
* @return 是否成功
*/
protected boolean trySync() {
try {
sync();
return true;
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
logger
.warn("Sync config failed, will retry. Repository {}, reason: {}", this.getClass(), ExceptionUtil
.getDetailMessage(ex));
}
return false;
}


解释:这一步主要是尝试同步,返回是否成功


进入sync()

protected synchronized void sync() {
Transaction transaction = Tracer.newTransaction("Apollo.ConfigService", "syncRemoteConfig");


try {
// 缓存中的ApolloConfig
ApolloConfig previous = m_configCache.get();
// 从ConfigServer获得ApolloConfig
ApolloConfig current = loadApolloConfig();


//reference equals means HTTP 304
// 如果不相等说明有更新,更新缓存
if (previous != current) {
logger.debug("Remote Config refreshed!");
m_configCache.set(current);
this.fireRepositoryChange(m_namespace, this.getConfig());
}


if (current != null) {
Tracer.logEvent(String.format("Apollo.Client.Configs.%s", current.getNamespaceName()),
current.getReleaseKey());
}


transaction.setStatus(Transaction.SUCCESS);
} catch (Throwable ex) {
transaction.setStatus(ex);
throw ex;
} finally {
transaction.complete();
}
}

 解释:

1、进入同步,分别从缓存和Config-Service里获取ApolloConfig,对比如果两个不相等,说明有更新,之后更新缓存

2、loadApolloConfig:是从Config-Service实时获取,对应主流程中的4.3实时查询


进入fireRepositoryChange(触发监听者们)

/**
* 触发监听器们
* @param namespace
* @param newProperties
*/
protected void fireRepositoryChange(String namespace, Properties newProperties) {
for (RepositoryChangeListener listener : m_listeners) {
try {
//通知本地监听者,更新内存配置,本地文件备份
listener.onRepositoryChange(namespace, newProperties);
} catch (Throwable ex) {
Tracer.logError(ex);
logger.error("Failed to invoke repository change listener {}", listener.getClass(), ex);
}
}
}



 总结:


1、初始化RemoteConfigRepository时查询Config-Service的变更配置

2、跟缓存做对比,如果不一样 说明有变更

3、通知本地监听者修改本地缓存,备份文件的值



备注:本文主要讲RemoteConfigRepository触发同步,将同步结果更新本地缓存,备份文件操作,具体如何同步请期待下节


文章转载自鲁班同学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论