redis分布式锁
程序员文章站
2024-01-12 22:16:28
1. redis分布式锁 1.1. 实现工具 1.2. redis配置 上述主要用到 redisPoolFactory方法,用来初始化jedispool,缓存等不需要用到可以删除 1.3. 引入springboot 参考 https://www.cnblogs.com/linjiqin/p/8003 ......
1. redis分布式锁
1.1. 实现工具
public class redistool { private static final string lock_success = "ok"; private static final string set_if_not_exist = "nx"; private static final string set_with_expire_time = "px"; private static final long release_success = 1l; /** * 尝试获取分布式锁 * @param jedis redis客户端 * @param lockkey 锁 * @param requestid 请求标识 * @param expiretime 超期时间 * @return 是否获取成功 */ public static boolean trygetdistributedlock(jedis jedis, string lockkey, string requestid, int expiretime) { string result = jedis.set(lockkey, requestid, set_if_not_exist, set_with_expire_time, expiretime); if (lock_success.equals(result)) { return true; } return false; } /** * 释放分布式锁 * @param jedis redis客户端 * @param lockkey 锁 * @param requestid 请求标识 * @return 是否释放成功 */ public static boolean releasedistributedlock(jedis jedis, string lockkey, string requestid) { string script = "if redis.call('get', keys[1]) == argv[1] then return redis.call('del', keys[1]) else return 0 end"; object result = jedis.eval(script, collections.singletonlist(lockkey), collections.singletonlist(requestid)); if (release_success.equals(result)) { return true; } return false; } }
1.2. redis配置
package com.zhiyis.common.config; import com.fasterxml.jackson.annotation.jsonautodetect; import com.fasterxml.jackson.annotation.propertyaccessor; import com.fasterxml.jackson.databind.objectmapper; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.value; import org.springframework.cache.cachemanager; import org.springframework.cache.annotation.cachingconfigurersupport; import org.springframework.cache.annotation.enablecaching; import org.springframework.cache.interceptor.keygenerator; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.data.redis.cache.rediscachemanager; import org.springframework.data.redis.connection.redisconnectionfactory; import org.springframework.data.redis.connection.jedis.jedisconnectionfactory; import org.springframework.data.redis.core.redistemplate; import org.springframework.data.redis.serializer.jackson2jsonredisserializer; import org.springframework.data.redis.serializer.stringredisserializer; import org.springframework.http.converter.json.jackson2objectmapperbuilder; import redis.clients.jedis.jedispool; import redis.clients.jedis.jedispoolconfig; import java.lang.reflect.method; @configuration @enablecaching public class redisconfig extends cachingconfigurersupport { private static logger logger = loggerfactory.getlogger(redisconfig.class); @value("${spring.redis.host}") private string redishost; @value("${spring.redis.port}") private int redisport; @value("${spring.redis.timeout}") private int redistimeout; @value("${spring.redis.password}") private string redisauth; @value("${spring.redis.database}") private int redisdb; @value("${spring.redis.pool.max-active}") private int maxactive; @value("${spring.redis.pool.max-wait}") private int maxwait; @value("${spring.redis.pool.max-idle}") private int maxidle; @value("${spring.redis.pool.min-idle}") private int minidle; @bean @override public keygenerator keygenerator() { return new keygenerator() { @override public object generate(object target, method method, object... params) { stringbuilder sb = new stringbuilder(); sb.append(target.getclass().getname()); sb.append(method.getname()); for (object obj : params) { sb.append(obj.tostring()); } return sb.tostring(); } }; } @bean public cachemanager rediscachemanager() { rediscachemanager cachemanager = new rediscachemanager(redistemplate()); //默认300秒过期 cachemanager.setdefaultexpiration(300); // 启动时加载远程缓存 cachemanager.setloadremotecachesonstartup(true); //是否使用前缀生成器 cachemanager.setuseprefix(true); return cachemanager; } @bean public redisconnectionfactory redisconnectionfactory() { jedispoolconfig poolconfig = new jedispoolconfig(); poolconfig.setmaxtotal(maxactive); poolconfig.setmaxidle(maxidle); poolconfig.setmaxwaitmillis(maxwait); poolconfig.setminidle(minidle); poolconfig.settestonborrow(true); poolconfig.settestonreturn(false); poolconfig.settestwhileidle(true); jedisconnectionfactory jedisconnectionfactory = new jedisconnectionfactory(poolconfig); jedisconnectionfactory.setpassword(redisauth); jedisconnectionfactory.sethostname(redishost); jedisconnectionfactory.setdatabase(redisdb); jedisconnectionfactory.setport(redisport); jedisconnectionfactory.settimeout(redistimeout); return jedisconnectionfactory; } @bean public redistemplate<string, object> redistemplate() { redistemplate<string, object> redistemplate = new redistemplate<>(); jackson2jsonredisserializer<object> serializer = jackson2jsonredisserializer(); redistemplate.setconnectionfactory(redisconnectionfactory()); redistemplate.setkeyserializer(new stringredisserializer()); redistemplate.setvalueserializer(serializer); redistemplate.sethashkeyserializer(new stringredisserializer()); redistemplate.sethashvalueserializer(serializer); return redistemplate; } @bean public jackson2jsonredisserializer<object> jackson2jsonredisserializer() { final jackson2jsonredisserializer<object> jackson2jsonredisserializer = new jackson2jsonredisserializer<>(object.class); final objectmapper objectmapper = jackson2objectmapperbuilder .json().build(); objectmapper.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any); objectmapper.enabledefaulttyping(objectmapper.defaulttyping.non_final); jackson2jsonredisserializer.setobjectmapper(objectmapper); return jackson2jsonredisserializer; } @bean public jedispool redispoolfactory() throws exception { jedispoolconfig jedispoolconfig = new jedispoolconfig(); jedispoolconfig.setmaxidle(maxidle); jedispoolconfig.setmaxwaitmillis(maxwait); // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true jedispoolconfig.setblockwhenexhausted(true); // 是否启用pool的jmx管理功能, 默认true jedispoolconfig.setjmxenabled(true); jedispool jedispool = new jedispool(jedispoolconfig, redishost, redisport, redistimeout, redisauth); return jedispool; } }
上述主要用到 redispoolfactory方法,用来初始化jedispool,缓存等不需要用到可以删除
1.3. 引入springboot
/** * redis分布式锁 * @author laoliangliang * @date 2019/2/12 16:49 */ @component public class redislock { @autowired private jedispool jedispool; public boolean lock(string lockkey, string requestid, int expiretime) { jedis jedis = jedispool.getresource(); return redistool.trygetdistributedlock(jedis, lockkey, requestid, expiretime); } public boolean unlock(string lockkey, string requestid) { jedis jedis = jedispool.getresource(); return redistool.releasedistributedlock(jedis, lockkey, requestid); } }
参考 https://www.cnblogs.com/linjiqin/p/8003838.html
推荐阅读
-
redis被注入了crackit,但是我关闭了持久化存储功能,如何确定我的服务器是否被黑过?
-
redis分布式锁
-
【Redis笔记】第3篇:redis.conf中持久化(Persistence)相关配置
-
深入剖析 redis 数据结构 redisObject
-
MySQL事务锁:Lock wait timeout exceeded; try restarting transaction
-
windows上redis安装和php的redis扩展安装
-
linux centos5.8 安装redis
-
分布式集群LINUX平台下_MySQL
-
Docker——Docker安装Redis4.0
-
Redis的启动和关闭(前台启动和后台启动)