Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature consistency naming snapshot #3

Open
wants to merge 12 commits into
base: feature_consistency
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.naming.pojo.Record;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* @author jack_xjdai
* @date 2020/4/15 09:50
* @description: 负责管理服务注册中心核心数据结构组件
*/
public abstract class AbstractRecordManager<T extends Record> implements RecordManager<T> {
// 读写锁
protected ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

// 核心数据结构
Map<String, Datum<T>> datums = new ConcurrentHashMap<>();

public Map<String, Datum<T>> getDatums() {
readLock();
try {
return datums;
} finally {
readUnlock();
}
}

public void setDatums(Map<String, Datum<T>> datums) {
writeLock();
try {
this.datums = datums;
} finally {
writeUnlock();
}
}

@Override
public void addDatum(String key, Datum<T> value) {
writeLock();
try {
datums.put(key, value);
} finally {
writeUnlock();
}
}

@Override
public void removeDatum(String key) {
writeLock();
try {
datums.remove(key);
} finally {
writeUnlock();
}
}

@Override
public byte[] getDatumsBytes() {
readLock();
try {
return JSON.toJSONBytes(datums);
} finally {
readUnlock();
}
}

void readLock() {
readWriteLock.readLock().lock();
}

void readUnlock() {
readWriteLock.readLock().unlock();
}

void writeLock() {
readWriteLock.writeLock().lock();
}

void writeUnlock() {
readWriteLock.writeLock().unlock();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.naming.core.Instances;

/**
* @author jack_xjdai
* @date 2020/4/11 20:50
* @description: 负责管理Instances数据
*/
public class InstancesManager extends AbstractRecordManager<Instances> {
private InstancesManager() {
}

private static class SingletonHolder {
private static InstancesManager INSTANCE = new InstancesManager();
}

public static InstancesManager getInstance() {
return InstancesManager.SingletonHolder.INSTANCE;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.naming.pojo.Record;

import java.util.Map;

/**
* @author Jack_xj Dai
* @description 存磁盘的记录的管理接口类
*/
public interface RecordManager<T extends Record> {
Map<String, Datum<T>> getDatums();

void setDatums(Map<String, Datum<T>> datums);

void addDatum(String key, Datum<T> value);

void removeDatum(String key);

byte[] getDatumsBytes();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.naming.core.Instances;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.misc.SwitchDomain;

/**
* @author jack_xjdai
* @date 2020/4/13 13:50
* @description: RecordManager工厂类
* Record是需要做落地磁盘快照的接口类
* 实现它的实体类都可以支持落地磁盘做快照
*/
public enum RecordManagerFactory {
SWITCH_DOMAIN("switchDomain", SwitchDomain.class, false, "switch_domain.data", "switch_domain.meta", SwitchDomainManager.getInstance()),
SERVICE("service", Service.class, true, "service.data", "service.meta", ServiceManager.getInstance()),
INSTANCES("instances", Instances.class, true, "instances.data", "instances.meta", InstancesManager.getInstance());

// 唯一标识
private String id;
// 存储数据的类型,即Datum<T extends Record>中的T
private Class clazz;
// 是否需要落地磁盘做快照
private Boolean isNeedSnapshot;
// 快照对应的数据文件名
private String snapshotDataFilename;
// 快照对应的元数据文件名
private String snapshotMetaFilename;
// 存储数据对应的RecordManager的实现类
private RecordManager recordManager;

RecordManagerFactory(String id,
Class clazz,
Boolean isNeedSnapshot,
String snapshotDataFilename,
String snapshotMetaFilename,
RecordManager recordManager) {
this.id = id;
this.clazz = clazz;
this.isNeedSnapshot = isNeedSnapshot;
this.snapshotDataFilename = snapshotDataFilename;
this.snapshotMetaFilename = snapshotMetaFilename;
this.recordManager = recordManager;
}

public String getId() {
return id;
}

public Class getClazz() {
return clazz;
}

public Boolean getNeedSnapshot() {
return isNeedSnapshot;
}

public String getSnapshotDataFilename() {
return snapshotDataFilename;
}

public String getSnapshotMetaFilename() {
return snapshotMetaFilename;
}

public RecordManager getRecordManager() {
return recordManager;
}

/**
* 根据id获取RecordManager
*
* @param id
* @return
*/
public static RecordManager determineRecordManager(String id) {
for (RecordManagerFactory recordManagerFactory : RecordManagerFactory.values()) {
if (recordManagerFactory.getId().equals(id)) {
return recordManagerFactory.getRecordManager();
}
}
throw new IllegalArgumentException("没有找到相对应的RecordManager");
}

/**
* 根据Datum的Value的类型确定RecordManager
*
* @param clazz
* @return
*/
public static RecordManager determineRecordManagerByClass(Class clazz) {
for (RecordManagerFactory recordManagerFactory : RecordManagerFactory.values()) {
if (recordManagerFactory.getClazz().equals(clazz)) {
return recordManagerFactory.getRecordManager();
}
}
throw new IllegalArgumentException("没有找到相对应的RecordManager");
}

/**
* 根据Datum的Value的类型确定RecordManagerFactory
*
* @param clazz
* @return
*/
public static RecordManagerFactory determineRecordManagerFactoryByClass(Class clazz) {
for (RecordManagerFactory recordManagerFactory : RecordManagerFactory.values()) {
if (recordManagerFactory.getClazz().equals(clazz)) {
return recordManagerFactory;
}
}
throw new IllegalArgumentException("没有找到相对应的RecordManagerFactory");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.naming.core.Service;

/**
* @author jack_xjdai
* @date 2020/4/11 20:50
* @description: 负责管理Service数据
*/
public class ServiceManager extends AbstractRecordManager<Service> {
private ServiceManager() {
}

private static class SingletonHolder {
private static ServiceManager INSTANCE = new ServiceManager();
}

public static ServiceManager getInstance() {
return ServiceManager.SingletonHolder.INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.naming.misc.SwitchDomain;

/**
* @author jack_xjdai
* @date 2020/4/11 20:50
* @description: 负责管理SwitchDomain数据
*/
public class SwitchDomainManager extends AbstractRecordManager<SwitchDomain> {
private SwitchDomainManager() {
}

private static class SingletonHolder {
private static SwitchDomainManager INSTANCE = new SwitchDomainManager();
}

public static SwitchDomainManager getInstance() {
return SingletonHolder.INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ public void updateTerm(long term) throws Exception {
}
}

/**
* 是否需要切换新老版本的存储形式
* 如果是老版本第一次切换到新版本,并且data目录有数据,则需要迁移到新版本
* 如果是老版本升级后,该目录应该是没有数据了
*
* @return
*/
public boolean isNeedSwitchStorage() {
try {
return listCaches().length > 0;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

private static String encodeFileName(String fileName) {
return fileName.replace(':', '#');
}
Expand Down
Loading