change: 缓存清理逻辑调整, 进一步减少内存的占用
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@ target/
|
|||||||
### 测试数据 ###
|
### 测试数据 ###
|
||||||
instances/
|
instances/
|
||||||
settings.properties
|
settings.properties
|
||||||
|
logback.xml
|
||||||
|
|
||||||
### Eclipse ###
|
### Eclipse ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.serliunx.ddns.config;
|
package com.serliunx.ddns.config;
|
||||||
|
|
||||||
import com.serliunx.ddns.support.Refreshable;
|
import com.serliunx.ddns.core.Refreshable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置信息逻辑定义
|
* 配置信息逻辑定义
|
||||||
|
|||||||
23
src/main/java/com/serliunx/ddns/core/Clearable.java
Normal file
23
src/main/java/com/serliunx/ddns/core/Clearable.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.serliunx.ddns.core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义一个实体的清理逻辑
|
||||||
|
* <li> 一般用来清理中间加载过程中所产生的无用对象
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Clearable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行清理
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体是否需要执行清理逻辑
|
||||||
|
* <li> 默认为真
|
||||||
|
* @return 是否需要执行清理逻辑
|
||||||
|
*/
|
||||||
|
default boolean isClearable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.serliunx.ddns.support;
|
package com.serliunx.ddns.core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新逻辑
|
* 刷新逻辑
|
||||||
@@ -12,9 +12,4 @@ public interface Refreshable {
|
|||||||
* 刷新(初始化)
|
* 刷新(初始化)
|
||||||
*/
|
*/
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新后逻辑定义, 一般用于资源清理
|
|
||||||
*/
|
|
||||||
default void afterRefresh(){}
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.serliunx.ddns.core.context;
|
package com.serliunx.ddns.core.context;
|
||||||
|
|
||||||
import com.serliunx.ddns.constant.InstanceType;
|
import com.serliunx.ddns.constant.InstanceType;
|
||||||
|
import com.serliunx.ddns.core.Clearable;
|
||||||
import com.serliunx.ddns.core.factory.ListableInstanceFactory;
|
import com.serliunx.ddns.core.factory.ListableInstanceFactory;
|
||||||
import com.serliunx.ddns.core.instance.Instance;
|
import com.serliunx.ddns.core.instance.Instance;
|
||||||
import com.serliunx.ddns.support.Assert;
|
import com.serliunx.ddns.support.Assert;
|
||||||
import com.serliunx.ddns.support.Refreshable;
|
import com.serliunx.ddns.core.Refreshable;
|
||||||
import com.serliunx.ddns.util.ReflectionUtils;
|
import com.serliunx.ddns.util.ReflectionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -59,9 +60,6 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
|
|||||||
Set<Instance> builtInstances = buildInstances(instances);
|
Set<Instance> builtInstances = buildInstances(instances);
|
||||||
|
|
||||||
instanceMap = builtInstances.stream().collect(Collectors.toMap(Instance::getName, i -> i));
|
instanceMap = builtInstances.stream().collect(Collectors.toMap(Instance::getName, i -> i));
|
||||||
|
|
||||||
// 调用善后处理钩子函数
|
|
||||||
afterRefresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,10 +110,16 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
|
|||||||
return listableInstanceFactories;
|
return listableInstanceFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
if(isClearable())
|
||||||
|
clear0();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 善后工作
|
* 子类清理逻辑
|
||||||
*/
|
*/
|
||||||
public abstract void afterRefresh();
|
protected abstract void clear0();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存清理
|
* 缓存清理
|
||||||
@@ -125,10 +129,11 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
|
|||||||
&& !cacheInstanceMap.isEmpty()){
|
&& !cacheInstanceMap.isEmpty()){
|
||||||
int size = cacheInstanceMap.size();
|
int size = cacheInstanceMap.size();
|
||||||
cacheInstanceMap.clear();
|
cacheInstanceMap.clear();
|
||||||
log.debug("缓存信息清理 => {} 条", size);
|
// 清理实例工厂的缓存信息
|
||||||
|
listableInstanceFactories.forEach(Clearable::clear);
|
||||||
|
listableInstanceFactories.clear();
|
||||||
|
log.info("共清理缓存信息 => {} 条", size);
|
||||||
}
|
}
|
||||||
// 清理实例工厂的缓存信息
|
|
||||||
listableInstanceFactories.forEach(Refreshable::afterRefresh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class FileInstanceContext extends AbstractInstanceContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterRefresh() {
|
protected void clear0() {
|
||||||
clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,13 @@ package com.serliunx.ddns.core.context;
|
|||||||
*/
|
*/
|
||||||
public class GenericInstanceContext extends AbstractInstanceContext {
|
public class GenericInstanceContext extends AbstractInstanceContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterRefresh() {
|
protected void clear0() {
|
||||||
clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClearable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
package com.serliunx.ddns.core.context;
|
package com.serliunx.ddns.core.context;
|
||||||
|
|
||||||
import com.serliunx.ddns.core.factory.InstanceFactory;
|
import com.serliunx.ddns.core.factory.InstanceFactory;
|
||||||
import com.serliunx.ddns.support.Refreshable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author SerLiunx
|
* @author SerLiunx
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface InstanceContext extends InstanceFactory, Refreshable {
|
public interface InstanceContext extends InstanceFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default int getPriority() {
|
default int getPriority() {
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ import static com.serliunx.ddns.util.InstanceUtils.validateInstance;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractInstanceFactory implements InstanceFactory, ListableInstanceFactory {
|
public abstract class AbstractInstanceFactory implements InstanceFactory, ListableInstanceFactory {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AbstractInstanceFactory.class);
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例信息
|
* 实例信息
|
||||||
*/
|
*/
|
||||||
private Map<String, Instance> instanceMap;
|
protected Map<String, Instance> instanceMap;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Instance getInstance(String instanceName) {
|
public Instance getInstance(String instanceName) {
|
||||||
@@ -76,13 +76,9 @@ public abstract class AbstractInstanceFactory implements InstanceFactory, Listab
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterRefresh() {
|
public final void clear() {
|
||||||
if (instanceMap != null
|
if(isClearable() && instanceMap != null)
|
||||||
&& !instanceMap.isEmpty()){
|
clear0();
|
||||||
int size = instanceMap.size();
|
|
||||||
instanceMap.clear();
|
|
||||||
log.debug("缓存信息清理 => {} 条", size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,4 +86,13 @@ public abstract class AbstractInstanceFactory implements InstanceFactory, Listab
|
|||||||
* @return 实例信息
|
* @return 实例信息
|
||||||
*/
|
*/
|
||||||
protected abstract Set<Instance> load();
|
protected abstract Set<Instance> load();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理逻辑
|
||||||
|
*/
|
||||||
|
protected void clear0(){
|
||||||
|
final int size = instanceMap.size();
|
||||||
|
instanceMap.clear();
|
||||||
|
log.info("缓存信息清理 => {} 条", size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package com.serliunx.ddns.core.factory;
|
package com.serliunx.ddns.core.factory;
|
||||||
|
|
||||||
|
import com.serliunx.ddns.core.Clearable;
|
||||||
import com.serliunx.ddns.core.Priority;
|
import com.serliunx.ddns.core.Priority;
|
||||||
import com.serliunx.ddns.core.instance.Instance;
|
import com.serliunx.ddns.core.instance.Instance;
|
||||||
import com.serliunx.ddns.support.Refreshable;
|
import com.serliunx.ddns.core.Refreshable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author SerLiunx
|
* @author SerLiunx
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface InstanceFactory extends Priority, Comparable<InstanceFactory>, Refreshable {
|
public interface InstanceFactory extends Priority, Comparable<InstanceFactory>, Refreshable, Clearable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加实例
|
* 添加实例
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.serliunx.ddns.core.instance;
|
|||||||
|
|
||||||
import com.serliunx.ddns.constant.InstanceSource;
|
import com.serliunx.ddns.constant.InstanceSource;
|
||||||
import com.serliunx.ddns.constant.InstanceType;
|
import com.serliunx.ddns.constant.InstanceType;
|
||||||
import com.serliunx.ddns.support.Refreshable;
|
import com.serliunx.ddns.core.Refreshable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author SerLiunx
|
* @author SerLiunx
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.serliunx.ddns.support;
|
|||||||
|
|
||||||
import com.serliunx.ddns.config.Configuration;
|
import com.serliunx.ddns.config.Configuration;
|
||||||
import com.serliunx.ddns.constant.SystemConstants;
|
import com.serliunx.ddns.constant.SystemConstants;
|
||||||
|
import com.serliunx.ddns.core.Clearable;
|
||||||
|
import com.serliunx.ddns.core.Refreshable;
|
||||||
import com.serliunx.ddns.core.context.MultipleSourceInstanceContext;
|
import com.serliunx.ddns.core.context.MultipleSourceInstanceContext;
|
||||||
import com.serliunx.ddns.core.instance.Instance;
|
import com.serliunx.ddns.core.instance.Instance;
|
||||||
import com.serliunx.ddns.support.feign.client.IPAddressClient;
|
import com.serliunx.ddns.support.feign.client.IPAddressClient;
|
||||||
@@ -33,7 +35,7 @@ import static com.serliunx.ddns.config.ConfigurationKeys.KEY_THREAD_POOL_CORE_SI
|
|||||||
* @author SerLiunx
|
* @author SerLiunx
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public final class SystemInitializer implements Refreshable {
|
public final class SystemInitializer implements Refreshable, Clearable {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SystemInitializer.class);
|
private static final Logger log = LoggerFactory.getLogger(SystemInitializer.class);
|
||||||
|
|
||||||
@@ -79,9 +81,18 @@ public final class SystemInitializer implements Refreshable {
|
|||||||
|
|
||||||
// 运行实例
|
// 运行实例
|
||||||
runInstances();
|
runInstances();
|
||||||
|
|
||||||
|
// 实例提交后, 清理实例、配置缓存, 因为读取一次就不需要了
|
||||||
|
clear();
|
||||||
log.info("初始化完成!");
|
log.info("初始化完成!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
instanceContext.clear();
|
||||||
|
instances.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public MultipleSourceInstanceContext getInstanceContext() {
|
public MultipleSourceInstanceContext getInstanceContext() {
|
||||||
return instanceContext;
|
return instanceContext;
|
||||||
}
|
}
|
||||||
@@ -90,11 +101,6 @@ public final class SystemInitializer implements Refreshable {
|
|||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterRefresh() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadInstances() {
|
private void loadInstances() {
|
||||||
instances = instanceContext.getInstances();
|
instances = instanceContext.getInstances();
|
||||||
log.info("载入 {} 个实例.", instances.size());
|
log.info("载入 {} 个实例.", instances.size());
|
||||||
@@ -166,7 +172,6 @@ public final class SystemInitializer implements Refreshable {
|
|||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
MDC.put("pid", SystemSupport.getPid());
|
MDC.put("pid", SystemSupport.getPid());
|
||||||
log.info("程序正在关闭中, 可能需要一定时间.");
|
log.info("程序正在关闭中, 可能需要一定时间.");
|
||||||
afterRefresh();
|
|
||||||
scheduledThreadPoolExecutor.shutdown();
|
scheduledThreadPoolExecutor.shutdown();
|
||||||
log.info("已关闭.");
|
log.info("已关闭.");
|
||||||
}, "DDNS-ShutDownHook"));
|
}, "DDNS-ShutDownHook"));
|
||||||
|
|||||||
Reference in New Issue
Block a user