Redis竞争锁失败异步获取兜底优化
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Redis竞争锁失败异步获取兜底优化,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2439字,纯文字阅读大概需要4分钟。
内容图文
优化前
//返回对象
Object result = null;
//分布式锁
String cacheLock = CacheUtil.genLockKey(cacheKey);
if (lock.lock(cacheLock, 5000, TimeUnit.MILLISECONDS)) {
try {
//业务方法查询逻辑
result = pjp.proceed();
if (Objects.nonNull(result)) {
rwxCache.set(cacheKey, JSON.toJSONString(result), 1, TimeUnit.HOURS);
}
} catch (Exception e) {
e.printStackTrace();
rwxCache.del(cacheKey);
} finally {
lock.unlock(cacheLock);
}
} else {
Future<String> future = taskExecutor.submit(() -> rwxCache.get(cacheKey));
try {
cache = future.get(500, TimeUnit.MILLISECONDS);
result = JSON.parseObject(cache, getReturnType(pjp));
} catch (Exception e) {
//important! 这里会有问题,一旦future超时,返回的是Object result = null;则没有信息返回,而此时是有可能有值的,应该抛出异常,而不是给一个不确定的结果
e.printStackTrace();
rwxCache.del(cacheKey);
}
}
return result;
优化后
//返回对象
Object result = null;
//防止缓存穿透
// rwxCache.set(cacheKey, CacheUtil.EMPTY, 1, TimeUnit.HOURS);
//分布式锁
String cacheLock = CacheUtil.genLockKey(cacheKey);
if (lock.lock(cacheLock, 5000, TimeUnit.MILLISECONDS)) {
LOGGER.debug("[CacheFilterAspect] cache lock get. key={}", cacheKey);
try {
//业务方法查询逻辑
result = pjp.proceed();
if (Objects.nonNull(result)) {
rwxCache.set(cacheKey, JSON.toJSONString(result), 1, TimeUnit.HOURS);
}
} catch (Exception e) {
e.printStackTrace();
rwxCache.del(cacheKey);
} finally {
lock.unlock(cacheLock);
}
} else {
LOGGER.info("[CacheFilterAspect] cache async get. key={}", cacheKey);
Future<String> future = taskExecutor.submit(() -> {
//如果分布式锁一直lock状态就进行自旋轮询,每隔Thread.sleep(10)毫秒轮询一次结果,future.get(500, TimeUnit.MILLISECONDS)除以Thread.sleep(100)就是轮询次数,超时则抛出异常
while (true) {
if (!lock.isLocked(cacheLock)) {
return rwxCache.get(cacheKey);
} else {
try {
//这里会影响tp999等SLA指标,比如时间间隔太短设置5ms,cpu空转锁没释放请求redis过于频繁造成浪费;设置时间间隔太长则tp999飙高,而且锁释放了还没发起请求,这里根据tp999情况适当设置即可
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
LOGGER.error("[CacheRemoveAspect] interval wait error.", e);
//发生异常,则抛出异常,不返回明确结果
throw e;
}
}
}
});
try {
//这里是极端情况下max的值
cache = future.get(500, TimeUnit.MILLISECONDS);
result = JSON.parseObject(cache, getReturnType(pjp));
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("[CacheFilterAspect] cache async get timeout failed.");
//发生异常,则抛出异常,不返回明确结果
throw e;
}
}
return result;
内容总结
以上是互联网集市为您收集整理的Redis竞争锁失败异步获取兜底优化全部内容,希望文章能够帮你解决Redis竞争锁失败异步获取兜底优化所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。