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

互动型网站长沙网站免费建站

互动型网站,长沙网站免费建站,临沂网站制作方案,自己做的网站放到首页SpringBoot第44讲#xff1a;SpringBoot集成Redis - Redis分布式锁的实现之Jedis(setNXPXLua) Redis实际使用场景最为常用的还有通过Redis实现分布式锁。本文是SpringBoot第44讲#xff0c;主要介绍Redis实现分布式锁 文章目录 SpringBoot第44讲#xff1a;SpringBoot集成Re…SpringBoot第44讲SpringBoot集成Redis - Redis分布式锁的实现之Jedis(setNXPXLua) Redis实际使用场景最为常用的还有通过Redis实现分布式锁。本文是SpringBoot第44讲主要介绍Redis实现分布式锁 文章目录 SpringBoot第44讲SpringBoot集成Redis - Redis分布式锁的实现之Jedis(setNXPXLua)1、知识准备1.1、什么是分布式锁分布式锁有哪些实现方式1.2、Redis的分布式锁有哪些实现方式 2、实现案例2.1、定义Redis的分布式锁类2.2、定义AOP拦截点2.3、定义AOP切面2.4、切面使用 3、示例源码 1、知识准备 需要了解为何要用分布式锁以及分布式锁常见的实现方式以及如何通过Redis实现分布式锁的几种方式。 1.1、什么是分布式锁分布式锁有哪些实现方式 分布式锁相关的内容请参考 分布式系统第四讲分布式锁及实现方案 1.2、Redis的分布式锁有哪些实现方式 主要有两种思路 单个Redis实例setnx(key,当前时间过期时间) LuaRedis集群模式Redlock 在实现使用时由于很多redis客户端包含了上述实现方式我们可以通过redis客户端进行更多可以看 分布式系统第四讲分布式锁及实现方案 2、实现案例 本案例主要介绍 基于Jedis客户端下通过 setnx(key, 当前时间过期时间) Lua 实现分布式锁 2.1、定义Redis的分布式锁类 具体看分布式系统 - 分布式锁及实现方案 中Redis实现分布式锁的部分 加锁 set NX PX 重试 重试间隔 向Redis发起如下命令: SET productId:lock 0xx9p03001 NX PX 30000 其中productId由自己定义可以是与本次业务有关的id0xx9p03001是一串随机值必须保证全局唯一(防止删除其他线程的锁可以使用traceid作为value)“NX指的是当且仅当key(也就是案例中的productId:lock”)在Redis中不存在时返回执行成功否则执行失败。PX 30000指的是在30秒后key将被自动删除。执行命令后返回成功表明服务成功的获得了锁。 解锁采用lua脚本 在删除key之前一定要判断服务A持有的value与Redis内存储的value是否一致。如果贸然使用服务A持有的key来删除锁则会误将服务B的锁释放掉。 if redis.call(get, KEYS[1])ARGV[1] thenreturn redis.call(del, KEYS[1]) elsereturn 0 end具体的封装类 RedisDistributedLock 如下 package springboot.redis.jedis.lock.lock;import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.StringRedisTemplate; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.commands.JedisCommands; import redis.clients.jedis.params.SetParams; import java.util.ArrayList; import java.util.List; import java.util.UUID;/*** author qiwenjie*/ Slf4j public class RedisDistributedLock {/*** lua script for unlock.*/private static final String UNLOCK_LUA;static {StringBuilder sb new StringBuilder();sb.append(if redis.call(\get\,KEYS[1]) ARGV[1] );sb.append(then );sb.append( return redis.call(\del\,KEYS[1]) );sb.append(else );sb.append( return 0 );sb.append(end );UNLOCK_LUA sb.toString();}/*** unique lock flag based on thread local.*/private final ThreadLocalString lockFlag new ThreadLocal();private final StringRedisTemplate redisTemplate;public RedisDistributedLock(StringRedisTemplate redisTemplate) {this.redisTemplate redisTemplate;}public boolean lock(String key, long expire, int retryTimes, long retryDuration) {// use JedisCommands instead of setIfAbsenseboolean result setRedis(key, expire);// retry if neededwhile ((!result) retryTimes-- 0) {try {log.debug(lock failed, retrying... retryTimes);Thread.sleep(retryDuration);} catch (Exception e) {return false;}// use JedisCommands instead of setIfAbsenseresult setRedis(key, expire);}return result;}private boolean setRedis(String key, long expire) {try {RedisCallbackString redisCallback connection - {JedisCommands commands (JedisCommands) connection.getNativeConnection();String uuid UUID.randomUUID().toString(); // change to distribute UUID generation.lockFlag.set(uuid);return commands.set(key, uuid, SetParams.setParams().nx().px(expire));};String result redisTemplate.execute(redisCallback);return !StringUtils.isEmpty(result);} catch (Exception e) {log.error(set redis occurred an exception, e);}return false;}public boolean unlock(String key) {boolean success false;try {ListString keys new ArrayList();keys.add(key);ListString args new ArrayList();args.add(lockFlag.get());// use lua scriptRedisCallbackLong redisCallback connection - {Object nativeConnection connection.getNativeConnection();if (nativeConnection instanceof JedisCluster) { // cluster modereturn (Long) ((JedisCluster) nativeConnection).eval(UNLOCK_LUA, keys, args);} else if (nativeConnection instanceof Jedis) { // single modereturn (Long) ((Jedis) nativeConnection).eval(UNLOCK_LUA, keys, args);}return 0L;};Long result redisTemplate.execute(redisCallback);success result ! null result 0;} catch (Exception e) {log.error(release lock occurred an exception, e);} finally {if (success) {lockFlag.remove();}}return success;} }2.2、定义AOP拦截点 定义RedisLock注解 package springboot.redis.jedis.lock.annotation;import java.lang.annotation.*;/*** author qiwenjie*/ Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited public interface RedisLock {/*** redis lock key as value.** return lock key*/String value() default ;/*** how long we hold the lock.** return mills*/long expireMills() default 30000;/*** if lock failed, do we need to retry, default retry 0 means NO retry.** return retry times*/int retryTimes() default 0;/*** when we retry to get lock, whats the duration for next retry.** return mills*/long retryDurationMills() default 200; }2.3、定义AOP切面 定义AOP切面类RedisLockAspect用来拦截RedisLock注解方法并调用RedisDistributedLock对方法加锁处理。 package springboot.redis.jedis.lock.lock;import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.annotation.Configuration; import springboot.redis.jedis.lock.annotation.RedisLock;import javax.annotation.Resource; import java.lang.reflect.Method; import java.util.Arrays;/*** author qiwenjie*/ Slf4j Aspect Configuration public class RedisLockAspect {/*** lock impl.*/Resourceprivate RedisDistributedLock distributedLock;/*** AOP, around PJP.** param pjp ProceedingJoinPoint* return Object* throws Throwable Throwable*/Around(annotation(springboot.redis.jedis.lock.annotation.RedisLock))public Object around(ProceedingJoinPoint pjp) throws Throwable {// get attribute through annotationMethod method ((MethodSignature) pjp.getSignature()).getMethod();RedisLock redisLock method.getAnnotation(RedisLock.class);String key redisLock.value();if (StringUtils.isEmpty(key)) {Object[] args pjp.getArgs();key Arrays.toString(args);}// do lockboolean lock distributedLock.lock(key, redisLock.expireMills(), redisLock.retryTimes(),redisLock.retryDurationMills());if (!lock) {// 加锁失败不执行业务逻辑log.debug(get lock failed, key: {}, key);return null;}// execute method, and unlocklog.debug(get lock success, key: {}, key);try {// executereturn pjp.proceed();} catch (Exception e) {log.error(execute locked method occurred an exception, e);} finally {// unlockboolean releaseResult distributedLock.unlock(key);log.debug(release lock: {}, success: {}, key, releaseResult);}return null;} }2.4、切面使用 只需要在对应方法添加RedisLock注解即可实现分布式锁 RedisLock public void xxxMethod() {}分布式锁在项目中的使用可以参考这篇文章 项目实战第四十二讲分布式环境下使用ResubmitCheck注解进行防重校验 3、示例源码 todo
http://www.hkea.cn/news/14508782/

相关文章:

  • 商城网站策划方案视频制作培训机构
  • wordpress仿站js如何导入燕莎做网站
  • 怎么做符合seo的网站免费做app的网站
  • 网站如何做参考文献西电信息化建设网站
  • 天津营销网站建设联系方式nginx 做udp网站
  • 网站开发公司的log互联网设计师前景如何
  • 宿州网站开发宁波建设网站制作
  • 最便宜买机票网站建设长沙装修网站排名
  • 电子商务网站建设收益深圳网站seo设计
  • 网站搭建视频广州优化公司推广
  • 生鲜网站建设的项目总结北京网站设计与建设
  • 长沙优化网站分析网站建设进度总结
  • 锦州网站建设预订wordpress替换谷歌字体插件
  • 做网站的一般步骤自贡企业网站
  • 公司手机网站开发没有影视许可怎么用国内空间做网站
  • 南通网站建设seo网站建设服务器都有哪些
  • 佛山营销型网站建设网站经营方案
  • 怎么建设个人网站 新手学做网站idc数据中心
  • 自助网站推广系统电子商务网站的规划与分析
  • 网站pc端和手机端分离怎么做投诉做网站的电话
  • 精品成品冈站源码免费网站设计书怎么写
  • 好看的网站建设seo权重查询
  • 威海住房和城乡建设局网站萍乡网站seo
  • 软件下载站网站源码免费有什么可以做兼职的正规网站
  • 高埗东莞微信网站建设橙色大气风格网站模板
  • 杭州品牌网站中建一局招聘网
  • 网站谁做的比较好看的优秀设计案例
  • 公司网站招聘费如何做会计分录网站建设文件夹布局
  • 网站设计联系方式多用户电商平台
  • 深圳专业建网站公司排行保定模板建站软件