Vesta发号器源码解析——MachineIdsIdServiceImpl
这个类是一个对IdServiceImpl的扩展,继承了IdServiceImpl,实现了多个Ids的扩展
相关字段
//记录最后的时间戳
protected long lastTimestamp = -1;
//MachineId的映射关系
protected Map<Long, Long> machineIdMap = new ConcurrentHashMap<Long, Long>();
//存储的文件
public static final String STORE_FILE_NAME = "machineIdInfo.store";
//存储路径
private String storeFilePath;
//存储文件
private File storeFile;
//锁,可重入锁
private Lock lock = new ReentrantLock();
初始化方法
重写父类中的初始化方法
@Override
public void init() {
//如果当前的MachinId的provider不是MachineIdsProvider接口的实现
if (!(this.machineIdProvider instanceof MachineIdsProvider)) {
log.error("The machineIdProvider is not a MachineIdsProvider instance so that Vesta Service refuses to start.");
throw new RuntimeException(
"The machineIdProvider is not a MachineIdsProvider instance so that Vesta Service refuses to start.");
}
//调用父类先初始化
super.init();
//初始化存储文件
initStoreFile();
//初始化MachineId
initMachineIhid();
}
重写Id生成方法
@Override
protected void populateId(Id id) {
//支持修改MachineId的方法调用
supportChangeMachineId(id);
}
支持修改MachineId的方法
private void supportChangeMachineId(Id id) {
try {
//设置machineId
id.setMachine(this.machineId);
//id生成器生成id
idPopulator.populateId(timer, id, idMeta);
//记录时间戳
this.lastTimestamp = id.getTime();
} catch (IllegalStateException e) {
//发生时钟回拨,记录日志
log.warn("Clock moved backwards, change MachineId and reset IdPopulator");
//加锁
lock.lock();
try {
//如果当前MachineID和id中的相同,修改MachineId然后重置Id生成器
if (id.getMachine() == this.machineId) {
changeMachineId();
resetIdPopulator();
}
} finally {
//解锁
lock.unlock();
}
//重新调用一次自己
supportChangeMachineId(id);
}
}
修改MachineId
protected void changeMachineId() {
//将当前的machineId和时间戳放到map里面
this.machineIdMap.put(this.machineId, this.lastTimestamp);
//存进文件里
storeInFile();
//初始化machineId
initMachineId();
}
重置生成器
protected void resetIdPopulator() {
//确保id生成器是可重置的
if (idPopulator instanceof ResetPopulator) {
//然后充值id生成器
((ResetPopulator) idPopulator).reset();
} else {
try {
//否则重新初始化一个Id生成器
IdPopulator newIdPopulator = this.idPopulator.getClass().newInstance();
this.idPopulator = newIdPopulator;
} catch (InstantiationException e1) {
//抛出重置失败
throw new RuntimeException("Reset IdPopulator <[" + this.idPopulator.getClass().getCanonicalName() + "]> instance error", e1);
} catch (IllegalAccessException e1) {
//抛出重置失败
throw new RuntimeException("Reset IdPopulator <[" + this.idPopulator.getClass().getCanonicalName() + "]> instance error", e1);
}
}
}
初始化存储文件
protected void initStoreFile() {
//存储文件的位置没初始化
if (storeFilePath == null || storeFilePath.length() == 0) {
//存储文件的路径设置好
//System.getProperty("user.dir")获取程序当前路径
storeFilePath = System.getProperty("user.dir") + File.separator + STORE_FILE_NAME;
}
try {
//记录日志
log.info("machineId info store in <[" + storeFilePath + "]>");
//存储文件初始化
storeFile = new File(storeFilePath);
//文件存在,写入
if (storeFile.exists(){
//逐行读取,然后初始化到map中
BufferedReader reader = new BufferedReader(new FileReader(storeFile));
String line = reader.readLine();
while (line != null && line.length() > 0) {
String[] kvs = line.split(":");
if (kvs.length == 2) {
this.machineIdMap.put(Long.parseLong(kvs[0]), Long.parseLong(kvs[1]));
} else {
throw new IllegalArgumentException(storeFile.getAbsolutePath() + " has illegal value <[" + line + "]>");
}
line = reader.readLine();
}
reader.close();
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
初始化机器Id
protected void initMachineId() {
//起始Id记录
long startId = this.machineId;
//新id记录
long newMachineId = this.machineId;
while (true) {
//如果新的machineId已经在map中存在了
if (this.machineIdMap.containsKey(newMachineId)) {
//获取新的时间戳
long timestamp = timer.genTime();
//如果新machineId的时间戳比获取的小
if (this.machineIdMap.get(newMachineId) < timestamp) {
//使用新的machineID
this.machineId = newMachineId;
break;
} else {
//否则获取下一个MachineId作为New
newMachineId = ((MachineIdsProvider) this.machineIdProvider).getNextMachineId();
}
//如果新的和开始的一样,说明没有id了
if (newMachineId == startId) {
throw new RuntimeException("No machineId is available");
}
//校验id是否合法,然后重新循环
validateMachineId(newMachineId);
} else {
//如果不包含直接设置为新的
//此处通常是上一轮循环到id校验合法,然后回来进入这里退出循环
this.machineId = newMachineId;
break;
}
}
//记录日志
log.warn("MachineId: {}", this.machineId);
}
存储进文件的方法
protected void storeInFile() {
//初始化Writer
Writer writer = null;
try {
//初始化文件写入,append参数为false,非追加模式
writer = new FileWriter(storeFile, false);
//循环,将map写入文件中
for (Map.Entry<Long, Long> entry : this.machineIdMap.entrySet()) {
writer.write(entry.getKey() + ":" + entry.getValue() + "\n");
}
} catch (IOException e) {
//写入异常,记录日志
log.error("Write machineId info to File<[" + storeFile.getAbsolutePath() + "]> error");
throw new RuntimeException("Write machineId info to File<[" + storeFile.getAbsolutePath() + "]> error");
} finally {
//关闭IO
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
}
}
}
}
设置存储文件的路径
//设置存储文件的位置
public void setStoreFilePath(String storeFilePath) {
this.storeFilePath = storeFilePath;
}