接口优化:查询企业额度代码优化
方案一、20分钟内没请求则会重新查询一次;20分钟内有请求则会走最小5分钟的异步更新
public long getleadsSurplusCountFast(String companyId) {
// 锁key
String lockKey = String.format("getleadsSurplusCountFastLock:%s", companyId);
// 缓存值key
String key = String.format("getleadsSurplusCountFast:%s", companyId);
// 异步更新key
String asyncKey = String.format("getleadsSurplusCountFastAsync:%s", companyId);
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock();
String cacheValue = stringRedisTemplate.opsForValue().get(key);
if (stringRedisTemplate.hasKey(asyncKey)) {
if (StrUtil.isNotBlank(cacheValue)) {
return Long.parseLong(cacheValue);
} else {
log.info("getleadsSurplusCountFast直接通过数据库查询:{}", companyId);
return cacheSurplusCount(companyId, key, asyncKey);
}
}else {
if (StrUtil.isBlank(cacheValue)) {
return cacheSurplusCount(companyId, key, asyncKey);
}
// 异步更新缓存
String requestId = MDC.get(MDC_REQUEST_ID);
queryUserUpperLimitPool.submit(
() -> {
MDC.put(MDC_REQUEST_ID, requestId);
log.info("getleadsSurplusCountFast异步通过数据库查询更新:{}", companyId);
cacheSurplusCount(companyId, key, asyncKey);
MDC.remove(MDC_REQUEST_ID);
}
);
return Long.parseLong(cacheValue);
}
} finally {
lock.forceUnlock();
}
}
缓存代码
private long cacheSurplusCount(String companyId, String key, String asyncKey) {
// 查询企业总额度
long leadsSurplusCount = this.leadsSurplusCount(companyId);
stringRedisTemplate.opsForValue().set(key, String.valueOf(leadsSurplusCount), Duration.ofMinutes(20));
stringRedisTemplate.opsForValue().set(asyncKey, "0", Duration.ofMinutes(5));
return leadsSurplusCount;
}
方案二、查询企业总额度除以100,当额度小于100时为实时查询,当计算出的缓存时间小于5秒时至少缓存5秒
public long getleadsSurplusCountByReduce(String companyId){
String lockKey = String.format("getleadsSurplusCountByReduceLock:%s", companyId);
String valueKey = String.format("getleadsSurplusCountByReduce:%s", companyId);
RLock lock = redissonClient.getLock(lockKey);
try {
lock.lock();
String cacheValue = stringRedisTemplate.opsForValue().get(valueKey);
if (StrUtil.isNotBlank(cacheValue)) {
return Long.parseLong(cacheValue);
} else {
long leadsSurplusCount = this.leadsSurplusCount(companyId);
if (leadsSurplusCount < 100) {
log.info("企业剩余额度告警:{},剩余额度:{}", companyId, leadsSurplusCount);
return leadsSurplusCount;
}
long residueCount = leadsSurplusCount / 100;
if (residueCount < 5) {
residueCount = 5;
}
log.info("企业剩余额度缓存:{},额度:{},缓存时间(单位s):{}", companyId, leadsSurplusCount, residueCount);
stringRedisTemplate.opsForValue().set(valueKey, String.valueOf(leadsSurplusCount), Duration.ofSeconds(residueCount));
return leadsSurplusCount;
}
} finally {
lock.forceUnlock();
}
}