代码实现:
@Data
public class HkBaseCache {
/**
* 表格类型List
*/
public static List<BaseCustomsClearanceParameters> tableTypeList = new ArrayList<>();
/**
* 协调制度编码Map key:协调制度编号 value:协调制度对象
*/
public static Map<String, BaseHarmonizedSystem> harmonizedMap = new ConcurrentHashMap<>();
/**
* 原产国与香港来源国关系Map key:原产国代码 value:原产国与香港来源国关系
*/
public static Map<String, CountryTurnRelation> countryTurnRelationMap = new ConcurrentHashMap<>();
/**
* 包装种类Map key:包装种类代码 value:包装种类信息
*/
public static Map<String, BaseCustomsClearanceParameters> packTypeMap = new HashMap<>();
/**
* 初始化
*
* @param stringRedisTemplate string序列化的
* @author wrx
* @date 2021/12/25 11:00
*/
public static HkBaseCache init(StringRedisTemplate stringRedisTemplate){
HkBaseCache hkBaseCache = new HkBaseCache();
hkBaseCache.loadCache(stringRedisTemplate);
return hkBaseCache;
}
/**
* 加载缓存
*
* @param stringRedisTemplate string序列化的
* @author wrx
* @date 2021/12/25 11:00
*/
private void loadCache(StringRedisTemplate stringRedisTemplate){
// 设置缓存中的表格类型
String tableTypeJson = stringRedisTemplate.opsForValue().get(RedisConstants.TZ_REDIS_BASE_CUSTOMS_CLEARANCE_PARAMETERS + BaseCustomsClearanceParametersEnum.TABLE_TYPE.getCode());
tableTypeList.clear();
tableTypeList = JSONUtil.toList(JSONUtil.parseArray(tableTypeJson), BaseCustomsClearanceParameters.class);
// 设置缓存中的协调制度编号
harmonizedMap.clear();
Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(RedisConstants.TZ_REDIS_BASE_HARMONIZED_SYSTEM);
entries.entrySet().parallelStream().forEach(entry-> harmonizedMap.put(StrUtil.toString(entry.getKey()),JSONUtil.toBean(StrUtil.toString(entry.getValue()),BaseHarmonizedSystem.class)));
// 设置缓存中的原产国关系
countryTurnRelationMap.clear();
Map<Object, Object> entries2 = stringRedisTemplate.opsForHash().entries(RedisConstants.TZ_REDIS_COUNTRY_TURN_RELATION);
entries2.entrySet().parallelStream().forEach(entry-> countryTurnRelationMap.put(StrUtil.toString(entry.getKey()),JSONUtil.toBean(StrUtil.toString(entry.getValue()),CountryTurnRelation.class)));
// 设置缓存中的包装种类
packTypeMap.clear();
String packTypeJson = stringRedisTemplate.opsForValue().get(RedisConstants.TZ_REDIS_BASE_CUSTOMS_CLEARANCE_PARAMETERS + BaseCustomsClearanceParametersEnum.PACK_TYPE.getCode());
List<BaseCustomsClearanceParameters> packTypeList = JSONUtil.toList(JSONUtil.parseArray(packTypeJson), BaseCustomsClearanceParameters.class);
packTypeMap = packTypeList.stream().collect(Collectors.toMap(BaseCustomsClearanceParameters::getCode, obj -> obj));
}
- 容器启动时,初始化
@SpringCloudApplication
@Slf4j
public class XXXApplication implements CommandLineRunner {
@Autowired
StringRedisTemplate stringRedisTemplate;
public static void main(String[] args) {
SpringApplication.run(XXXApplication.class,args);
}
@Override
public void run(String... args) throws Exception {
log.info("---------初始化工作 start----------");
stringRedisTemplate.init();
log.info("---------初始化工作 end----------");
}
}
缺点:
- 需要维护本地缓存,所以本地缓存的数据尽量是恒古不变的
- 数据存储在元空间,注意自己的JVM设置是否合理
关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N,对于64位JVM来说,元空间的默认初始大小是21MB,默认的元空间的最大值是无限。
-XX:MaxMetaspaceSize: 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小。
-XX:MetaspaceSize: 指定元空间的初始空间大小, 以字节为单位,默认是21M,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。
由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。
如何判断对象占用的空间?
- pom依赖
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>8.3.0</version>
</dependency>
- 调用api计算
long byteCount = RamUsageEstimator.shallowSizeOf(obj);
得到的是字节数