From 83b424045ec2c28357b725b4dcd05a8852926a87 Mon Sep 17 00:00:00 2001 From: wangfushun Date: Sun, 25 Oct 2020 22:01:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0redisson=E7=9A=84redis?= =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=EF=BC=8C=E5=88=86=E5=B8=83=E5=BC=8F?= =?UTF-8?q?=E9=94=81=EF=BC=8C=E5=9C=A8=E4=BB=BB=E5=8A=A1=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD=E9=9C=80=E8=A6=81=E4=BF=9D=E8=AF=81=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E4=BD=BF=E7=94=A8=20=E4=BE=8B=E5=A6=82=EF=BC=9A${redi?= =?UTF-8?q?sson.redis.lock(oneCategroyUrl)}=20=E5=8F=AA=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E9=94=81=EF=BC=8C=E6=B2=A1=E6=9C=89=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E9=94=81=EF=BC=8C=E5=9B=A0=E4=B8=BA=E6=AF=8F?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E8=8A=82=E7=82=B9=E7=9A=84=E9=83=BD=E6=98=AF?= =?UTF-8?q?=E5=8D=95=E7=8B=AC=E7=9A=84=E7=BA=BF=E7=A8=8B=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=EF=BC=8C=E6=89=80=E4=BB=A5=E9=87=8A=E6=94=BE=E5=92=8C=E5=8A=A0?= =?UTF-8?q?=E9=94=81=E5=9C=A8=E4=B8=A4=E4=B8=AA=E7=BA=BF=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E5=9B=A0=E6=AD=A4=E6=97=A0=E6=B3=95=E5=9C=A8=E5=8F=A6=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E7=BA=BF=E7=A8=8B=E9=87=8A=E6=94=BE=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../function/RedissonFunctionExecutor.java | 122 ++++++++++++++++++ .../redis/service/RedissonSourceService.java | 43 ++++++ .../spiderflow/redis/utils/RedisUtils.java | 22 ++++ 4 files changed, 192 insertions(+) create mode 100644 src/main/java/org/spiderflow/redis/executor/function/RedissonFunctionExecutor.java create mode 100644 src/main/java/org/spiderflow/redis/service/RedissonSourceService.java diff --git a/pom.xml b/pom.xml index ae6767f..5a17880 100644 --- a/pom.xml +++ b/pom.xml @@ -26,5 +26,10 @@ redis.clients jedis + + org.redisson + redisson + 3.13.4 + diff --git a/src/main/java/org/spiderflow/redis/executor/function/RedissonFunctionExecutor.java b/src/main/java/org/spiderflow/redis/executor/function/RedissonFunctionExecutor.java new file mode 100644 index 0000000..631d70d --- /dev/null +++ b/src/main/java/org/spiderflow/redis/executor/function/RedissonFunctionExecutor.java @@ -0,0 +1,122 @@ +package org.spiderflow.redis.executor.function; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.redisson.api.RLock; +import org.redisson.api.RReadWriteLock; +import org.redisson.api.RedissonClient; +import org.spiderflow.annotation.Comment; +import org.spiderflow.annotation.Example; +import org.spiderflow.executor.FunctionExecutor; +import org.spiderflow.expression.DynamicMethod; +import org.spiderflow.redis.model.RedisSource; +import org.spiderflow.redis.service.RedisSourceService; +import org.spiderflow.redis.service.RedissonSourceService; +import org.spiderflow.redis.utils.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.stereotype.Component; +import redis.clients.util.SafeEncoder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Component +@Comment("redisson常用方法") +public class RedissonFunctionExecutor extends HashMap implements FunctionExecutor{ + + private static final long serialVersionUID = 924273531304909956L; + + public static volatile Map REDIS_CACHED_TEMPLATE = new HashMap(); + + private static RedissonSourceService redissonSourceService; + + @Override + public String getFunctionPrefix() { + return "redisson"; + } + + private static RedissonClient findRedisTemplate(String alias){ + RedissonClient redissonClient = REDIS_CACHED_TEMPLATE.get(alias); + if(redissonClient == null){ + RedisSource redisSource = redissonSourceService.getOne(new QueryWrapper().eq("alias", alias).orderByDesc("create_date")); + if(redisSource == null){ + throw new NullPointerException("找不到Redis数据源'" + alias +"'"); + } + redissonClient = RedisUtils.createRedisson(redisSource); + REDIS_CACHED_TEMPLATE.put(alias, redissonClient); + } + return redissonClient; + } + + + + @Override + public Object get(Object key) { + return use(key == null ? null : key.toString()); + } + + @Comment("选择数据源") + @Example("${redisson.use('aliasName')}或${redisson.aliasName}") + public static synchronized DynamicMethod use(String alias){ + return createDynamicMethod(alias,findRedisTemplate(alias)); + } + + private static DynamicMethod createDynamicMethod(String alias,RedissonClient redisson){ + return new DynamicMethod() { + + @Override + public Object execute(String methodName, List parameters){ + + if(parameters==null || parameters.size()==0 || parameters.size()>2){ + return null; + } + + String key=parameters.get(0).toString(); + Integer waitTime=10; + if(parameters.size()==2){ + try { + Integer time = Integer.parseInt(parameters.get(0).toString()); + if (time != null) { + waitTime = time; + } + }catch (Exception e){ + + } + } + + ; + + switch (methodName){ + case "lock": + try { + RLock lock=null; + lock = redisson.getLock(key); + lock.tryLock(100, waitTime, TimeUnit.SECONDS); + }catch (InterruptedException e){ + }finally { } + return 1; + case "unlock": + //获得锁的线程不是释放锁的线程, + return 1; + default: + return null; + } + } + + + }; + } + + @Autowired + public void setRedisSourceService(RedissonSourceService redissonSourceService) { + RedissonFunctionExecutor.redissonSourceService = redissonSourceService; + } + +} diff --git a/src/main/java/org/spiderflow/redis/service/RedissonSourceService.java b/src/main/java/org/spiderflow/redis/service/RedissonSourceService.java new file mode 100644 index 0000000..354dc85 --- /dev/null +++ b/src/main/java/org/spiderflow/redis/service/RedissonSourceService.java @@ -0,0 +1,43 @@ +package org.spiderflow.redis.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.redisson.api.RedissonClient; +import org.spiderflow.redis.executor.function.RedisFunctionExecutor; +import org.spiderflow.redis.executor.function.RedissonFunctionExecutor; +import org.spiderflow.redis.mapper.RedisSourceMapper; +import org.spiderflow.redis.model.RedisSource; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.io.Serializable; + +@Service +public class RedissonSourceService extends ServiceImpl{ + + @Override + public boolean saveOrUpdate(RedisSource entity) { + if(entity.getId() != null){ + removeOldRedisTemplate(entity.getId()); + } + return super.saveOrUpdate(entity); + } + + @Override + public boolean removeById(Serializable id) { + removeOldRedisTemplate(id); + return super.removeById(id); + } + + private void removeOldRedisTemplate(Serializable id){ + RedisSource oldSource = getById(id); + if(oldSource != null){ + RedissonClient redisson = RedissonFunctionExecutor.REDIS_CACHED_TEMPLATE.get(oldSource.getAlias()); + if(redisson != null){ + redisson.shutdown(); + } + RedissonFunctionExecutor.REDIS_CACHED_TEMPLATE.remove(oldSource.getAlias()); + } + } + +} diff --git a/src/main/java/org/spiderflow/redis/utils/RedisUtils.java b/src/main/java/org/spiderflow/redis/utils/RedisUtils.java index 4dc1677..9367815 100644 --- a/src/main/java/org/spiderflow/redis/utils/RedisUtils.java +++ b/src/main/java/org/spiderflow/redis/utils/RedisUtils.java @@ -1,5 +1,8 @@ package org.spiderflow.redis.utils; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; import org.spiderflow.redis.model.RedisSource; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; @@ -7,6 +10,7 @@ import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.util.StringUtils; import redis.clients.jedis.JedisPoolConfig; public class RedisUtils { @@ -25,6 +29,24 @@ public class RedisUtils { StringRedisTemplate redisTemplate = new StringRedisTemplate(new JedisConnectionFactory(standaloneConfiguration,jedisConfigConfiguration)); return redisTemplate; } + + public static RedissonClient createRedisson(String host,Integer port,String password,Integer database,Integer poolMaxActive,Integer poolMaxIdle,Integer poolMinIdle){ + // 1. Create config object + Config config = new Config(); + config.useSingleServer() + // use "rediss://" for SSL connection + .setAddress("redis://"+host+":"+port) + .setDatabase(database) + .setConnectTimeout(30) + .setPassword(StringUtils.isEmpty(password)?null:password); + // Sync and Async API + RedissonClient redisson = Redisson.create(config); + return redisson; + } + + public static RedissonClient createRedisson(RedisSource redisSource){ + return createRedisson(redisSource.getHost(), redisSource.getPort(), redisSource.getPassword(), redisSource.getDbIndex(), redisSource.getMaxConnections(), redisSource.getMaxIdle(), redisSource.getMinIdle()); + } public static StringRedisTemplate createRedisTemplate(RedisSource redisSource){ return createRedisTemplate(redisSource.getHost(), redisSource.getPort(), redisSource.getPassword(), redisSource.getDbIndex(), redisSource.getMaxConnections(), redisSource.getMaxIdle(), redisSource.getMinIdle()); -- Gitee