Nacos 설정 센터 디자인 분석 - 클 라 이언 트
주요 기능
Nacos 설정 센터 클 라 이언 트 는 주로 다음 과 같은 능력 을 가지 고 있 습 니 다.
// NacosConfigService
public NacosConfigService(Properties properties) throws NacosException {
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
if (StringUtils.isBlank(encodeTmp)) {
encode = Constants.ENCODE;
} else {
encode = encodeTmp.trim();
}
initNamespace(properties);
// HTTP MetricsHttpAgent
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start();
// ClientWorker
worker = new ClientWorker(agent, configFilterChainManager, properties);
}
중요 데이터 구조
NacosConfigService
// NacosConfigService
public class NacosConfigService implements ConfigService {
......
// http MetricsHttpAgent
private HttpAgent agent;
//
private ClientWorker worker;
......
}
EventDispatcher
public class EventDispatcher {
......
// key ,value
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP
= new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
......
}
ServerListManager
// ServerListManager
public class ServerListManager {
......
// ( )
private String serverAddrsStr;
// ( serverAddrsStr )
volatile List<String> serverUrls = new ArrayList<String>();
// ( )
public String addressServerUrl;
......
}
ClientWorker
// ClientWorker
public class ClientWorker {
// ,key ,value CacheData
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<String, CacheData>());
}
CacheData
// CacheData
public class CacheData {
//
private volatile String content;
//
private final CopyOnWriteArrayList<ManagerListenerWrap> listeners;
}
CacheData 는 파일 캐 시 를 설정 합 니 다. CacheData 에서 파일 내용 을 가 져 옵 니 다. CacheData 는 클 라 이언 트 스 레 드 에서 업 데 이 트 를 계속 끌 어 옵 니 다.
전형 적 인 장면
프로필 내용 가 져 오기
로 컬 캐 시 파일 에서 프로필 내용 을 우선 읽 고 실패 하면 서버 에서 가 져 오고 실패 하면 과거 기록 스냅 샷 파일 에서 가 져 옵 니 다.
// NacosConfigService
private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
...
//
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
if (content != null) {
......
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
......
return content;
}
//
try {
String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(ct[0]);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
return content;
} catch (NacosException ioe) {
if (NacosException.NO_RIGHT == ioe.getErrCode()) {
throw ioe;
}
LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
agent.getName(), dataId, group, tenant, ioe.toString());
}
//
LOGGER.warn("[{}] [get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", agent.getName(),
dataId, group, tenant, ContentUtils.truncateContent(content));
content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
cr.setContent(content);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
return content;
}
프로필 내용 발표
API 를 호출 하여 프로필 내용 을 수정 합 니 다.
프로필 감청 추가
클 라 이언 트 가 지정 한 파일 내용 을 정시 에 끌 어 옵 니 다. 변화 가 발생 하면 설정 파일 내용 을 업데이트 하고 (cacheMap 에 저장) 감청 기 를 호출 하여 해당 하 는 처 리 를 합 니 다. 파일 모니터링 코드 를 추가 하면 다음 과 같 습 니 다.
// ClientWorker
public void checkConfigInfo() {
//
int listenerSize = cacheMap.get().size();
//
// ParamUtil.getPerTaskConfigSize() , , cacheMap
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
if (longingTaskCount > currentLongingTaskCount) {
for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
// 。 。
executorService.execute(new LongPollingRunnable(i));
}
currentLongingTaskCount = longingTaskCount;
}
}
파일 내용 을 끌 어 내 고 코드 를 다음 과 같이 업데이트 합 니 다.
// ClientWorker
class LongPollingRunnable implements Runnable {
private int taskId;
public LongPollingRunnable(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
List<CacheData> cacheDatas = new ArrayList<CacheData>();
List<String> inInitializingCacheList = new ArrayList<String>();
try {
// check failover config
for (CacheData cacheData : cacheMap.get().values()) {
if (cacheData.getTaskId() == taskId) {
cacheDatas.add(cacheData);
try {
checkLocalConfig(cacheData);
if (cacheData.isUseLocalConfigInfo()) {
cacheData.checkListenerMd5();
}
} catch (Exception e) {
LOGGER.error("get local config info error", e);
}
}
}
// check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
LOGGER.info("get changedGroupKeys:" + changedGroupKeys);
for (String groupKey : changedGroupKeys) {
String[] key = GroupKey.parseKey(groupKey);
String dataId = key[0];
String group = key[1];
String tenant = null;
if (key.length == 3) {
tenant = key[2];
}
try {
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
//
cache.setContent(ct[0]);
if (null != ct[1]) {
cache.setType(ct[1]);
}
LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}, type={}",
agent.getName(), dataId, group, tenant, cache.getMd5(),
ContentUtils.truncateContent(ct[0]), ct[1]);
} catch (NacosException ioe) {
String message = String.format(
"[%s] [get-update] get changed config exception. dataId=%s, group=%s, tenant=%s",
agent.getName(), dataId, group, tenant);
LOGGER.error(message, ioe);
}
}
for (CacheData cacheData : cacheDatas) {
if (!cacheData.isInitializing() || inInitializingCacheList
.contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant))) {
//
cacheData.checkListenerMd5();
cacheData.setInitializing(false);
}
}
inInitializingCacheList.clear();
executorService.execute(this);
} catch (Throwable e) {
// If the rotation training task is abnormal, the next execution time of the task will be punished
LOGGER.error("longPolling error : ", e);
executorService.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS);
}
}
}
프로필 감청 삭제
// ClientWorker
public void removeListener(String dataId, String group, Listener listener) {
group = null2defaultGroup(group);
CacheData cache = getCache(dataId, group);
if (null != cache) {
cache.removeListener(listener);
if (cache.getListeners().isEmpty()) {
removeCache(dataId, group);
}
}
}
스 레 드 모델
Nacos 서버 로그 인 라인
본 고 는 Nacos 의 1.2.0 버 전 을 바탕 으로 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.