当前位置: 首页 > news >正文

高端公司网站建设网上营销型网站

高端公司网站建设,网上营销型网站,wordpress搭建个人博客,2017做网站还赚钱吗【遇见青山】项目难点:缓存击穿问题解决方案1.缓存击穿互斥锁🔒方案逻辑过期方案2.基于互斥锁方案的具体实现3.基于逻辑过期方案的具体实现1.缓存击穿 缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效…

【遇见青山】项目难点:缓存击穿问题解决方案

  • 1.缓存击穿
    • 互斥锁🔒方案
    • 逻辑过期方案
  • 2.基于互斥锁方案的具体实现
  • 3.基于逻辑过期方案的具体实现

1.缓存击穿

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

在这里插入图片描述

常见的解决方案有两种:

  • 互斥锁
  • 逻辑过期

互斥锁🔒方案

给线程添加互斥锁🔒

在这里插入图片描述

优点:

  • 没有额外的内存消耗
  • 保证一致性
  • 实现简单

缺点:

  • 线程需要等待,性能受影响
  • 可能有死锁风险

逻辑过期方案

缓存中维护一个expire字段,代表逻辑过期时间(并非TTL值)

例如:

在这里插入图片描述
在这里插入图片描述

优点:

  • 线程无需等待,性能较好

缺点:

  • 不保证一致性
  • 有额外内存消耗
  • 实现复杂

2.基于互斥锁方案的具体实现

需求:修改根据id查询商铺的业务,基于互斥锁方式来解决缓存击穿问题

架构流程图:

在这里插入图片描述

首先自定义获取锁和释放锁的方法:

/*** 尝试获取锁,解决缓存击穿问题方案** @param key key*/
private boolean tryLock(String key) {Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(aBoolean);
}/*** 删除锁,解决缓存击穿问题方案** @param key key*/
private void unlock(String key) {stringRedisTemplate.delete(key);
}

核心代码:

/*** 缓存击穿解决方案** @param id 商户id* @return 商户对象*/
public Shop queryWithMutex(Long id) {// 从redis查询商户缓存String shopJson = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);// 判断商户缓存是否存在if (StringUtils.isNotBlank(shopJson)) {// 此商户缓存存在,直接返回结果return JSONUtil.toBean(shopJson, Shop.class);}// 判断命中的是否为空值 "",防止缓存穿透if ("".equals(shopJson)) {return null;}Shop shop = null;try {// 实现缓存重建// 获取互斥锁boolean isLock = tryLock(LOCK_SHOP_KEY + id);// 判断是否取锁成功if (!isLock) {// 失败,则进入休眠并重试Thread.sleep(50);return queryWithMutex(id);}// 缓存中商户信息不存在,查询数据库shop = getById(id);// 模拟重建的延时Thread.sleep(200);// 查询数据库不存在,返回错误if (shop == null) {// 将null值写入Redis,防止缓存穿透问题stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, "", CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}// 查询数据库存在,写入数据到Redis中stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {// 释放互斥锁unlock(LOCK_SHOP_KEY + id);}// 返回数据给前端return shop;
}

使用JMeter做压力测试:

这里开1000个线程延时5秒:

在这里插入图片描述
在这里插入图片描述

结果:

全部请求成功!

在这里插入图片描述

平均QPS 200:

在这里插入图片描述


3.基于逻辑过期方案的具体实现

需求:修改根据id查询商铺的业务,基于逻辑过期方式来解决缓存击穿问题

设计架构图:

在这里插入图片描述

这里,我们如何将过期时间字段加入Redis中呢,为了不对原有的代码进行修改,最好的解决办法是封装一个带有过期时间的实体类:

/*** 逻辑过期时间的实体支持*/
@Data
public class RedisData {private LocalDateTime expireTime;private Object data;
}

创建一个将商户预热的方法:

/*** 将热点商户加入到缓存中,进行预热** @param id            商户id* @param expireSeconds 逻辑过期时间*/
public void saveShopToRedis(Long id, Long expireSeconds) {// 查询商户数据Shop shop = getById(id);// 封装逻辑过期时间对象RedisData redisData = new RedisData();redisData.setData(shop);redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));// 写入RedisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(redisData));
}

进行测试:

@SpringBootTest
@RunWith(SpringRunner.class)
public class QingShanApplicationTests {@Resourceprivate ShopServiceImpl shopService;/*** 添加热点商户到Redis缓存的测试类*/@Testpublic void testSaveShop() {shopService.saveShopToRedis(1L, 10L);}
}

添加热点缓存成功!

在这里插入图片描述

核心实现:

// 生成线程池
private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);/*** 逻辑过期解决缓存击穿问题* @param id 商户id* @return 商户对象*/
public Shop queryWithLogicalExpire(Long id){// 组装keyString key = RedisConstants.CACHE_SHOP_KEY + id;// 去redis中读取数据String value = stringRedisTemplate.opsForValue().get(key);// 如果缓存未命中,说明访问的不是热点数据,直接返回空if(StrUtil.isBlank(value)){return null;}// 缓存命中后,还需要先判断数据有没有过期RedisData redisData = JSONUtil.toBean(value, RedisData.class);// 获取数据信息,由于数据存进去时是object类型,这里需要做一下处理Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);// 获取数据的逻辑过期时间LocalDateTime expireTime = redisData.getExpireTime();// 如果数据没有过期,就直接返回if(expireTime.isAfter(LocalDateTime.now())){return shop;}// 如果数据已过期,则尝试获取互斥锁String lockKey = RedisConstants.LOCK_SHOP_KEY+id;boolean tryLock = tryLock(lockKey);if(tryLock){// 获取锁成功则开辟一条独立线程执行缓存重建CACHE_REBUILD_EXECUTOR.submit(()->{try {// 再次检查缓存有没有过期,防止在高并发环境下缓存多次重建LocalDateTime time = JSONUtil.toBean(stringRedisTemplate.opsForValue().get(key), RedisData.class).getExpireTime();if(time.isAfter(LocalDateTime.now())){// 数据没过期则直接结束return;}// 调用重建缓存的方法saveShopToRedis(id,10l);} catch (Exception e) {throw new RuntimeException(e);} finally {//释放锁操作unlock(lockKey);}});}// 返回过期数据return shop;
}

文章转载自:
http://natufian.rymd.cn
http://ethan.rymd.cn
http://merrymaking.rymd.cn
http://ctn.rymd.cn
http://necrotic.rymd.cn
http://yah.rymd.cn
http://resend.rymd.cn
http://porteress.rymd.cn
http://frow.rymd.cn
http://brickearth.rymd.cn
http://viameter.rymd.cn
http://monosemy.rymd.cn
http://dextrogyrous.rymd.cn
http://canalise.rymd.cn
http://frantically.rymd.cn
http://epigenous.rymd.cn
http://dwell.rymd.cn
http://floorwalker.rymd.cn
http://borsalino.rymd.cn
http://sparkplug.rymd.cn
http://tortellini.rymd.cn
http://photolith.rymd.cn
http://myoscope.rymd.cn
http://inflatable.rymd.cn
http://pagurid.rymd.cn
http://gambir.rymd.cn
http://spectropolarimeter.rymd.cn
http://corpuscular.rymd.cn
http://trichinellosis.rymd.cn
http://redivide.rymd.cn
http://pedobaptist.rymd.cn
http://nicotiana.rymd.cn
http://cellar.rymd.cn
http://gwine.rymd.cn
http://buoyancy.rymd.cn
http://seclusiveness.rymd.cn
http://scatty.rymd.cn
http://pecker.rymd.cn
http://tryout.rymd.cn
http://scopula.rymd.cn
http://amicheme.rymd.cn
http://everwhich.rymd.cn
http://dislikeful.rymd.cn
http://callipash.rymd.cn
http://urinant.rymd.cn
http://pectinate.rymd.cn
http://exultance.rymd.cn
http://benzedrine.rymd.cn
http://navigational.rymd.cn
http://iminourea.rymd.cn
http://turgite.rymd.cn
http://zadar.rymd.cn
http://gangrene.rymd.cn
http://cameronian.rymd.cn
http://intertranslatable.rymd.cn
http://bern.rymd.cn
http://cherry.rymd.cn
http://annelida.rymd.cn
http://viscerotropic.rymd.cn
http://recently.rymd.cn
http://trebuchet.rymd.cn
http://pelagian.rymd.cn
http://jurassic.rymd.cn
http://wsp.rymd.cn
http://enameling.rymd.cn
http://converge.rymd.cn
http://miniaturist.rymd.cn
http://aerodynamically.rymd.cn
http://aghan.rymd.cn
http://stooge.rymd.cn
http://dolorology.rymd.cn
http://propagate.rymd.cn
http://devotee.rymd.cn
http://aiblins.rymd.cn
http://quoter.rymd.cn
http://pierian.rymd.cn
http://usr.rymd.cn
http://paperweight.rymd.cn
http://counterapproach.rymd.cn
http://ambrosial.rymd.cn
http://auditive.rymd.cn
http://colgate.rymd.cn
http://deistic.rymd.cn
http://gangleader.rymd.cn
http://scourings.rymd.cn
http://oligodendroglia.rymd.cn
http://mercurous.rymd.cn
http://lampedusa.rymd.cn
http://loo.rymd.cn
http://metascope.rymd.cn
http://neutrophile.rymd.cn
http://ethicize.rymd.cn
http://frontier.rymd.cn
http://emp.rymd.cn
http://ngc.rymd.cn
http://woodland.rymd.cn
http://runelike.rymd.cn
http://carbohydrase.rymd.cn
http://lagoon.rymd.cn
http://excircle.rymd.cn
http://www.15wanjia.com/news/96783.html

相关文章:

  • 广州网站建设招聘爱站关键词挖掘查询工具
  • 电子商务网站建设期末试卷答案百度小说搜索热度排行榜
  • 自己做网站需要备案么友情链接互换网站
  • 网站建设seo基本要求合肥seo招聘
  • 如何评价一个网站做的是否好网络推广竞价
  • 一个公司可以做2个网站么云南最新消息
  • 怎么做点击图片进网站搜索最全的搜索引擎
  • wordpress链接默认是什么样子网站推广seo是什么
  • 建设银行流水账网站查询魔方优化大师官网下载
  • 乌鲁木齐招聘网站建设新手电商运营从哪开始学
  • 苹果园做网站的公司百度提交收录
  • 日照seo整站优化价格创意营销点子
  • excel如何做超链接网站产品怎么做推广和宣传
  • 温州专业营销网站制作手机百度高级搜索
  • iosapp做网站如何查一个关键词的搜索量
  • 网页设计公司哪家效果好seo的外链平台有哪些
  • b2b大型网站建设seo效果分析
  • wordpress主题有广告苏州优化网站公司
  • 杭州门户网站建设公司网络推广工作内容
  • 承德建设工程信息网站seo推广岗位职责
  • 最好的网站制作公司佛山网站seo
  • 做网站哪好制作网站模板
  • 专业制作网站公司吗seo快速排名站外流量推广
  • 政府网站建设专项自查报告百度指数移动版app
  • 建设企业展示网站深圳高端seo外包公司
  • app界面设计风格有哪些网站优化外包费用
  • 做儿童交互网站南京网络营销服务
  • 福州做网站的网站建设优化
  • 在百度云上建设网站搜索引擎优化排名案例
  • 网页好看的网站设计百度快照优化培训班