Redis使用redisson-Lock底层看门狗原理和配置解析-----Redis
Redis使用redisson-Lock底层看门狗原理和配置解析-----Redis
·
package com.alatus.mall.product.web; import com.alatus.mall.product.entity.CategoryEntity; import com.alatus.mall.product.service.CategoryService; import com.alatus.mall.product.vo.SubCatalogVo; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @Controller public class IndexController { @Autowired private CategoryService categoryService; @Autowired private RedissonClient redisson; @GetMapping({"/","/index.html"}) public String indexPage(Model model){ List<CategoryEntity> categoryEntities = categoryService.getLevelCategories(1); // 视图解析器会自动拼串,不需要写具体位置和html后缀 model.addAttribute("categories",categoryEntities); return "index"; } @GetMapping("/index/catalog.json") @ResponseBody public Map<String, List<SubCatalogVo>> getCatalogJson(){ return categoryService.getCatalogJson(); } @GetMapping("/hello") @ResponseBody public String hello(){ // 获取一把锁,只要名字一样,就必定是同一把锁,底层用的原理还是redis RLock rLock = redisson.getLock("rLock"); rLock.lock(); // 加锁 // 加的锁会自带阻塞式等待,默认锁的时间是30s // 锁会自动续期,如果业务超长,会自动给锁续上30s,不用像我们手动加锁一样,担心锁被自动删除 // 只要业务完成,就不会续期,即使不手动解锁,也会在30s后删除 // 只要我们没配置过期时间,占锁成功就会启动一个定时任务,会自动给锁设置过期时间,新的过期时间就是看门狗的默认时间 // 相当于每隔10s都会自动续期 // rLock.lock(10, TimeUnit.SECONDS); // 相对来说,更推荐的是指定时间的方式,因为这样可以减少定时任务带来的损耗 // 自己设置了锁的持续时间以后,会导致超时自动续时间失败 // 其他服务就能抢到锁了 // 因此,我们设置的自动解锁时间一定是要大于我们的业务执行时间的 // 如果我们传递了锁的超时时间,就会发给redis执行lua脚本,底层还是lua脚本的形式 // 默认时间就被修改为我们传递的时间了 // 默认时间是底层配置的看门狗cfg时间30*1000 // 只要占锁成功,就会启动一个定时任务,重新给锁设置新的过期时间 // 默认的续期触发是看门狗时间除以三 try{ System.out.println("加锁成功执行业务"); Thread.sleep(30000); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { // 解锁,假设业务代码出现问题或是没有执行,redisson也不会出现死锁 rLock.unlock(); // 如果其他服务抢到了这个锁,执行删除,逻辑判断就会发现锁不对 // 会导致我们的删锁操作失败并报错 } return "Hello"; } }
package com.alatus.mall.product.web; import com.alatus.mall.product.entity.CategoryEntity; import com.alatus.mall.product.service.CategoryService; import com.alatus.mall.product.vo.SubCatalogVo; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @Controller public class IndexController { @Autowired private CategoryService categoryService; @Autowired private RedissonClient redisson; @GetMapping({"/","/index.html"}) public String indexPage(Model model){ List<CategoryEntity> categoryEntities = categoryService.getLevelCategories(1); // 视图解析器会自动拼串,不需要写具体位置和html后缀 model.addAttribute("categories",categoryEntities); return "index"; } @GetMapping("/index/catalog.json") @ResponseBody public Map<String, List<SubCatalogVo>> getCatalogJson(){ return categoryService.getCatalogJson(); } @GetMapping("/hello") @ResponseBody public String hello(){ // 获取一把锁,只要名字一样,就必定是同一把锁,底层用的原理还是redis RLock rLock = redisson.getLock("rLock"); rLock.lock(); // 加锁 // 加的锁会自带阻塞式等待,默认锁的时间是30s // 锁会自动续期,如果业务超长,会自动给锁续上30s,不用像我们手动加锁一样,担心锁被自动删除 // 只要业务完成,就不会续期,即使不手动解锁,也会在30s后删除 // 只要我们没配置过期时间,占锁成功就会启动一个定时任务,会自动给锁设置过期时间,新的过期时间就是看门狗的默认时间 // 相当于每隔10s都会自动续期 // rLock.lock(10, TimeUnit.SECONDS); // 相对来说,更推荐的是指定时间的方式,因为这样可以减少定时任务带来的损耗 // 自己设置了锁的持续时间以后,会导致超时自动续时间失败 // 其他服务就能抢到锁了 // 因此,我们设置的自动解锁时间一定是要大于我们的业务执行时间的 // 如果我们传递了锁的超时时间,就会发给redis执行lua脚本,底层还是lua脚本的形式 // 默认时间就被修改为我们传递的时间了 // 默认时间是底层配置的看门狗cfg时间30*1000 // 只要占锁成功,就会启动一个定时任务,重新给锁设置新的过期时间 // 默认的续期触发是看门狗时间除以三 try{ System.out.println("加锁成功执行业务"); Thread.sleep(30000); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { // 解锁,假设业务代码出现问题或是没有执行,redisson也不会出现死锁 rLock.unlock(); // 如果其他服务抢到了这个锁,执行删除,逻辑判断就会发现锁不对 // 会导致我们的删锁操作失败并报错 } return "Hello"; } }
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)