国内做网站上市公司,百万网站建设报价,苏州网站建设多少钱,门户网站是如何做引流的文章目录 演示代码本地缓存数据存入文件从文件提取数据到本地缓存工具类 实战初始化操作执行 本地缓存数据存入文件 的线程任务持久化工具类 演示代码
本地缓存数据存入文件 public static void testQ15() {LinkedBlockingDequeConcurrentHashMapString, ConcurrentHa… 文章目录 演示代码本地缓存数据存入文件从文件提取数据到本地缓存工具类 实战初始化操作执行 本地缓存数据存入文件 的线程任务持久化工具类 演示代码
本地缓存数据存入文件 public static void testQ15() {LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer failureStatusCache new LinkedBlockingDeque(4);LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer successStatusCache new LinkedBlockingDeque(4);LinkedBlockingDequeConcurrentHashMapString, Integer pushedStateCache new LinkedBlockingDeque(4);ObjectOutputStream oos null;// 初始化数据ConcurrentHashMapString, ConcurrentHashMapInteger, Integer mapF new ConcurrentHashMap();mapF.put(失败数据, new ConcurrentHashMapInteger, Integer() {{put(1, 0);}});failureStatusCache.add(mapF);ConcurrentHashMapString, ConcurrentHashMapInteger, Integer mapS new ConcurrentHashMap();mapS.put(成功数据, new ConcurrentHashMapInteger, Integer() {{put(2, 0);}});successStatusCache.add(mapS);pushedStateCache.add(new ConcurrentHashMapString, Integer() {{put(哈哈哈, 3);}});log.info(【SoulCache - saveData】持久化数据到文件);try {oos new ObjectOutputStream(Files.newOutputStream(Paths.get(PersistencePath.createFile(tzh))));oos.writeObject(failureStatusCache);oos.writeObject(successStatusCache);oos.writeObject(pushedStateCache);log.info(【SoulCache - saveData】持久化数据到文件 | 结束);} catch (Exception e) {log.error(保存持久化文件异常, e);} finally {try {if (oos ! null) {oos.close();}} catch (IOException ioe) {log.error(IO流关闭异常, ioe);}}}从文件提取数据到本地缓存
提取数据顺序必须和存入顺序一致,不然会报错
public static void testQ16() {ObjectInputStream ois null;try {String path PersistencePath.getPath(tzh);log.info(【SoulCache - loadData】加载到内存开始... | path:{}, path);ois new ObjectInputStream(Files.newInputStream(Paths.get(path)));LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer failureStatusCache (LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer) ois.readObject();LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer successStatusCache (LinkedBlockingDequeConcurrentHashMapString, ConcurrentHashMapInteger, Integer) ois.readObject();LinkedBlockingDequeConcurrentHashMapString, Integer pushedStateCache (LinkedBlockingDequeConcurrentHashMapString, Integer) ois.readObject();System.out.println(失败数据:failureStatusCache.getFirst().toString());System.out.println(成功数据:successStatusCache.getFirst().toString());System.out.println(pushedStateCache.getFirst().toString());log.info(【SoulCache - loadData】加载到内存 结束);} catch (Exception e) {log.error(加载内存持久化文件异常, e);} finally {try {if (ois ! null) {ois.close();}PersistencePath.delFile(tzh);} catch (IOException ioe) {log.error(IO流关闭异常, ioe);}}}工具类
public class PersistencePath {private static final Logger logger LoggerFactory.getLogger(PersistencePath.class);/*** 定时快照* ps:只针对状态报告*/private static AtomicInteger aofVersion new AtomicInteger(0);/*** Docker容器中对应持久化目录挂载到宿主机的相同名称目录* /test:./PersistenceData*/private final static String path /Users/zeki/test/;//服务id 需要在不同的实现工程中自己去注入值 例如在网关项目中代表网关idpublic static String serverId1;//服务名称 需要在不同的实现工程中自己去注入值public static String serverNametitan;private static String getAofVersion(){String _v DateUtil.formatDateyyyyMMddHHmmss(System.currentTimeMillis()) _ aofVersion.get();aofVersion.incrementAndGet();return _v;}/*** 持久化文件的名字 与服务名、服务id有关* ps: 例子 视频网关集群里面网关id为1的持久化文件名称为 sms-vms-gateway1.obj* return*/private static String buildFileName(){return String.format(%s%s.obj, Optional.ofNullable(serverName).orElse(defaultServerName()), serverId);}/*** 持久化文件的名字 与服务名、服务id有关* ps: 例子 视频网关集群里面网关id为1的持久化文件名称为 sms-vms-gateway1.obj20210407120000_1* return*/private static String buildFileName_AOF(){return buildFileName().concat(getAofVersion());}/*** 持久化文件的名字 与服务名、服务id有关* ps: 例子 视频网关集群里面网关id为1的持久化文件名称为 sms-vms-gateway1.obj* param prefixName 可能一个应用系统里面会有多个持久化文件 通过这个参数指定名称* return*/private static String buildFileName(String prefixName){return String.format(%s%s_%s.obj, Optional.ofNullable(serverName).orElse(defaultServerName()), serverId, prefixName);}/*** 获取文件路径* return 文件存在返回文件路径不存在返回null* throws IOException*/public static String getPath() {String fileName buildFileName();File file new File(path, fileName);if (file.exists()) {return path fileName;}logger.warn(getPath {}{} 不存在,path,fileName);return null;}/*** 获取文件路径* return 文件存在返回文件路径不存在返回null* throws IOException*/public static String getPath_AOF() {String fileName buildFileName_AOF();File file new File(path, fileName);if (file.exists()) {return path fileName;}return null;}/*** 获取文件路径* return 文件存在返回文件路径不存在返回null* param prefixName 可能一个应用系统里面会有多个持久化文件 通过这个参数指定名称* throws IOException*/public static String getPath(String prefixName) {String fileName buildFileName(prefixName);File file new File(path, fileName);if (file.exists()) {return path fileName;}return null;}/*** 创建文件* return* throws IOException*/public static String createFile() throws IOException {String fileName buildFileName();File file new File(path, fileName);if (!file.exists()) { //文件不存在创建file.createNewFile();}return path fileName;}/*** 创建文件* return* throws IOException*/public static String createFile_AOF() throws IOException {String fileName buildFileName_AOF();File file new File(path, fileName);if (!file.exists()) { //文件不存在创建file.createNewFile();}return path fileName;}/*** 创建文件* param prefixName 可能一个应用系统里面会有多个持久化文件 通过这个参数指定名称* return* throws IOException*/public static String createFile(String prefixName) throws IOException {String fileName buildFileName(prefixName);File file new File(path, fileName);if (!file.exists()) { //文件不存在创建file.createNewFile();}return path fileName;}/*** 删除文件* return* throws IOException*/public static boolean delFile() {String fileName buildFileName();File file new File(path, fileName);if (file.exists()) {return file.delete();}return false;}/*** 删除文件* param prefixName 可能一个应用系统里面会有多个持久化文件 通过这个参数指定名称* return* throws IOException*/public static boolean delFile(String prefixName) {String fileName buildFileName(prefixName);File file new File(path, fileName);if (file.exists()) {FileUtil.rename(file, String.format(%s_bak_%s_%s,fileName,cn.hutool.core.date.DateUtil.today(),IdUtil.fastSimpleUUID()), false, true);return true;}return false;}/*** 默认服务名*/private static String defaultServerName() {return Optional.ofNullable(SpringUtil.getApplicationContext()).map(ApplicationContext::getApplicationName).orElse(NULL);}
}实战
初始化操作
implements CommandLineRunner项目开始则执行以下代码,做个钩子,项目关闭时会触发该线程业务逻辑
Overridepublic void run(String... args) {// 狗子Runtime.getRuntime().addShutdownHook(new Thread(shutdownHook));}执行 本地缓存数据存入文件 的线程任务
这里的init方法是项目一启动会执行,将文件数据放进本地缓存中初始化这里的run方法是线程执行业务,项目结束运行,钩子触发该业务将本地缓存数据存放进文件中
Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
Component
public class ShutdownHook implements Runnable{private final static Logger log LoggerFactory.getLogger(ShutdownHook.class);private static final ListPersistence canBeHookList new ArrayList();Value(${server-node.id})private String nodeId;Value(${spring.application.name})private String applicationName;Resourceprivate MonitorThread monitorThread;PostConstructpublic void init() {PersistencePath.serverId nodeId;PersistencePath.serverName applicationName;//对内存数据进行初始化SmsQueueManage.getInstance().loadLocalData();MemoryParamCache.getInstance().loadLocalData();}Overridepublic void run() {Thread.currentThread().setName(ShutdownHook_Thread);log.info(【sms-rules退出 - Thread:{}】- 钩子回调 开始...,Thread.currentThread().getName());monitorThread.stopMonitorAndAllThread();try {Thread.sleep(1000);} catch (InterruptedException e) {log.error(Thread.currentThread().getName() : 线程休眠异常 ,e);}log.info(等待持久化队列管理类 size:{},canBeHookList.size());for (Persistence q : canBeHookList) {q.saveData();}log.error(【sms-rules退出 - Thread:{}】- 钩子回调 完毕,Thread.currentThread().getName());}public static void add(Persistence p) {canBeHookList.add(p);}public static void remove(Persistence p) {canBeHookList.remove(p);}
}持久化工具类
public class MemoryParamCache implements Persistence {private final static Logger log LoggerFactory.getLogger(MemoryParamCache.class);/*** 号段持久化文件名称前缀*/private static final String memoryParamCachePrefixFileName memoryParamCache;private volatile static MemoryParamCache instance;private MemoryParamCache(){ShutdownHook.add(this);}public static MemoryParamCache getInstance(){if (null instance) {synchronized (MemoryParamCache.class) {if (null instance) {instance new MemoryParamCache();}}}return instance;}Overridepublic void saveData() {ObjectOutputStream oos null;String path ;try {path PersistencePath.createFile(memoryParamCachePrefixFileName);log.info(【MemoryParamCache - saveData】持久化内存参数到文件 | 开始 | path:{},path);oos new ObjectOutputStream(new FileOutputStream(path));oos.writeObject(RuleSymbol.cityMap);log.info(【MemoryParamCache - saveData】持久化内存参数到文件 | 结束 | path:{} | cityMap:{},path , RuleSymbol.cityMap.size());} catch (Exception e) {log.error(【MemoryParamCache - 持久化内存参数到文件】异常 | path:{},path, e);} finally {try {if (oos ! null) {oos.close();}} catch (IOException ioe) {// ignore}}}/*** 磁盘上的缓存数据加载到内存*/public void loadLocalData() {ObjectInputStream ois null;String path ;try {path PersistencePath.getPath(memoryParamCachePrefixFileName);log.info(【MemoryParamCache - loadLocalData】内存参数缓存文件--------加载到内存开始... | path:{},path);ois new ObjectInputStream(new FileInputStream(path));RuleSymbol.cityMap (ConcurrentHashMapString, String) ois.readObject();log.info(【MemoryParamCache - loadLocalData】内存参数缓存文件--------加载到内存 结束 | path:{} | cityMap:{},path, RuleSymbol.cityMap.size());}catch (Exception e) {log.error(【sms-rules启动 - 加载持久化后的内存参数】异常 | path:{}, path,e);}finally {if(ois ! null){try {ois.close();} catch (IOException e) {// ignore}boolean b PersistencePath.delFile(memoryParamCachePrefixFileName);log.info(【MemoryParamCache - loadLocalData】STEP-TWO 删除缓存数据文件:{},b);}}}}