
net.hasor.rsf.address.DiskCacheAddressPool Maven / Gradle / Ivy
The newest version!
package net.hasor.rsf.address;
import net.hasor.rsf.RsfEnvironment;
import net.hasor.rsf.RsfSettings;
import net.hasor.rsf.domain.RsfConstants;
import net.hasor.rsf.utils.IOUtils;
import net.hasor.utils.MatchUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 服务地址的辅助工具,负责读写本地地址本缓存。
* @version : 2014年9月12日
* @author 赵永春 ([email protected])
*/
public class DiskCacheAddressPool extends AddressPool {
protected final Logger logger = LoggerFactory.getLogger(getClass());
private final AtomicBoolean inited = new AtomicBoolean(false);
private final Thread timer;
private final File snapshotHome;
private final File indexFile;
private boolean exitThread = false;
public DiskCacheAddressPool(final RsfEnvironment rsfEnvironment) {
super(rsfEnvironment);
File rsfHome = new File(rsfEnvironment.evalString("%RSF_DATA_HOME%/"));
this.snapshotHome = new File(rsfHome, RsfConstants.SnapshotPath);
this.indexFile = new File(snapshotHome, RsfConstants.SnapshotIndex);
//
this.timer = new Thread(new Runnable() {
public void run() {
if (rsfEnvironment.getSettings().islocalDiskCache()) {
doWork();
}
}
});
this.timer.setContextClassLoader(rsfEnvironment.getClassLoader());
this.timer.setName("RSF-DiskCacheAddressPool-Timer");
this.timer.setDaemon(true);
}
/** 启动定时器,定时进行地址本的磁盘缓存。*/
public void startTimer() {
if (this.inited.compareAndSet(false, true)) {
this.logger.info("startTimer address snapshot Thread[{}].", timer.getName());
this.exitThread = false;
this.timer.start();
}
}
/** 停止定时器,停止定时进行地址本的磁盘缓存。*/
public void shutdownTimer() {
if (this.inited.compareAndSet(true, false)) {
this.logger.info("shutdownTimer address snapshot Thread[{}].", timer.getName());
this.exitThread = true;
}
}
private void doWork() {
this.exitThread = false;
RsfSettings rsfSettings = this.getRsfEnvironment().getSettings();
long refreshCacheTime = rsfSettings.getRefreshCacheTime();
long diskCacheTimeInterval = rsfSettings.getDiskCacheTimeInterval();
long nextCheckSavePoint = 0;
//
if (diskCacheTimeInterval <= 0) {
diskCacheTimeInterval = RsfConstants.OneHourTime;
}
//
this.logger.info("AddressPool - Timer -> start, refreshCacheTime = {}.", refreshCacheTime);
while (!this.exitThread) {
//1.启动时做一次清理
clearCacheData();
try {
Thread.sleep(refreshCacheTime);
} catch (InterruptedException e) {
/**/
}
//2.将数据保存到缓存文件
this.logger.info("AddressPool - refreshCache. at = {} , refreshCacheTime = {}.", nowTime(), refreshCacheTime);
this.refreshAddressCache();
if (rsfSettings.islocalDiskCache() && nextCheckSavePoint < System.currentTimeMillis()) {
nextCheckSavePoint = System.currentTimeMillis() + diskCacheTimeInterval;/*每小时保存一次地址本快照。*/
try {
storeConfig();
} catch (IOException e) {
this.logger.error("saveAddress error {} -> {}", e.getMessage(), e);
}
}
}
this.logger.info("AddressPool - Timer -> stop.");
}
/**清理缓存的地址数据*/
public void clearCacheData() {
String[] fileNames = this.snapshotHome.list((dir, name) -> {
return MatchUtils.wildToRegex("address-[0-9]{8}-[0-9]{6}.zip", name, MatchUtils.MatchTypeEnum.Regex);
});
List sortList = (fileNames == null) ? new ArrayList(0) : Arrays.asList(fileNames);
Collections.sort(sortList);
//
long nowTime = System.currentTimeMillis() - RsfConstants.SevenDaysTime;//数据自动清理 7 天之前的数据
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss");
for (String itemName : sortList) {
try {
String dateTimeStr = itemName.substring(RsfConstants.AddrPoolStoreName.length(), itemName.length() - ".zip".length());
Date dateTime = format.parse(dateTimeStr);
if (dateTime.getTime() < nowTime) {
new File(this.snapshotHome, itemName).delete();
}
} catch (Exception e) { /**/ }
}
}
//
/**保存地址列表到zip流中(每小时保存一次),当遇到保存的文件已存在时会重新生成新的文件名。*/
public synchronized void storeConfig() throws IOException {
File writeFile = null;
while (writeFile == null || writeFile.exists()) {
writeFile = new File(this.snapshotHome, RsfConstants.AddrPoolStoreName + nowTime() + ".zip");
}
this.logger.info("rsf - saveAddress to snapshot file({}) ->{}", writeFile);
FileOutputStream fos = null;
FileWriter fw = null;
try {
boolean mkdirResult = writeFile.getParentFile().mkdirs();
if (mkdirResult || writeFile.getParentFile().exists()) {
fos = new FileOutputStream(writeFile, false);
fos.getFD().sync();//独占文件
//
this.storeConfig(fos);
//
fos.flush();
fos.close();
//
fw = new FileWriter(this.indexFile, false);
this.logger.info("rsf - update snapshot index -> " + this.indexFile.getAbsolutePath());
fw.write(writeFile.getName());
fw.flush();
fw.close();
}
} catch (IOException e) {
this.logger.error("rsf - saveAddress " + e.getClass().getSimpleName() + " :" + e.getMessage(), e);
throw e;
} finally {
if (fos != null) {
fos.close();
}
if (fw != null) {
fw.close();
}
}
}
/**从保存的地址本中恢复数据。*/
public synchronized void restoreConfig() {
//1.校验
if (!this.indexFile.exists()) {
this.logger.info("address snapshot index file, undefined.");
return;
}
if (!this.indexFile.canRead()) {
this.logger.error("address snapshot index file, can not read.");
return;
}
//2.确定要读取的文件。
File readFile = null;
try {
FileReader reader = new FileReader(this.indexFile);
List bodyList = IOUtils.readLines(reader);
String index = bodyList.isEmpty() ? "" : bodyList.get(0);
readFile = new File(this.snapshotHome, index);
if ("".equals(index) || !readFile.exists()) {
this.logger.error("address snapshot file is not exist.", readFile);
return;
}
} catch (Throwable e) {
this.logger.error("read the snapshot file name error :" + e.getMessage(), e);
return;
}
//
//3.恢复数据数据
FileInputStream inStream = null;
try {
inStream = new FileInputStream(readFile);
this.restoreConfig(inStream);
inStream.close();
} catch (IOException e) {
this.logger.error("read the snapshot file name error :" + e.getMessage(), e);
if (inStream != null) {
try {
inStream.close();
} catch (IOException e1) {
this.logger.error(e1.getMessage(), e1);
}
}
}
}
private static String nowTime() {
return new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy