| | |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.cache.RedisCacheConfiguration; |
| | | import org.springframework.data.redis.cache.RedisCacheManager; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.core.script.DefaultRedisScript; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * redis配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | @EnableCaching |
| | | public class RedisConfig extends CachingConfigurerSupport |
| | | { |
| | | public class RedisConfig extends CachingConfigurerSupport { |
| | | @Bean |
| | | @SuppressWarnings(value = { "unchecked", "rawtypes" }) |
| | | public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) |
| | | { |
| | | @SuppressWarnings(value = {"unchecked", "rawtypes"}) |
| | | public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { |
| | | RedisTemplate<Object, Object> template = new RedisTemplate<>(); |
| | | template.setConnectionFactory(connectionFactory); |
| | | |
| | |
| | | } |
| | | |
| | | @Bean |
| | | public DefaultRedisScript<Long> limitScript() |
| | | { |
| | | public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { |
| | | // 默认缓存配置(其他 cache 使用) |
| | | RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig(); |
| | | // 单独为 sfStatistics 设置 20 分钟 TTL |
| | | Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); |
| | | configMap.put("sfStatistics", defaultConfig.entryTtl(Duration.ofMinutes(20))); |
| | | configMap.put("sfStatisticsJoy", defaultConfig.entryTtl(Duration.ofMinutes(20))); |
| | | configMap.put("selectPatMedOuthospList", defaultConfig.entryTtl(Duration.ofMinutes(20))); |
| | | return RedisCacheManager.builder(connectionFactory).cacheDefaults(defaultConfig).withInitialCacheConfigurations(configMap).build(); |
| | | } |
| | | |
| | | @Bean |
| | | public DefaultRedisScript<Long> limitScript() { |
| | | DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(); |
| | | redisScript.setScriptText(limitScriptText()); |
| | | redisScript.setResultType(Long.class); |
| | |
| | | /** |
| | | * 限流脚本 |
| | | */ |
| | | private String limitScriptText() |
| | | { |
| | | return "local key = KEYS[1]\n" + |
| | | "local count = tonumber(ARGV[1])\n" + |
| | | "local time = tonumber(ARGV[2])\n" + |
| | | "local current = redis.call('get', key);\n" + |
| | | "if current and tonumber(current) > count then\n" + |
| | | " return tonumber(current);\n" + |
| | | "end\n" + |
| | | "current = redis.call('incr', key)\n" + |
| | | "if tonumber(current) == 1 then\n" + |
| | | " redis.call('expire', key, time)\n" + |
| | | "end\n" + |
| | | "return tonumber(current);"; |
| | | private String limitScriptText() { |
| | | return "local key = KEYS[1]\n" + "local count = tonumber(ARGV[1])\n" + "local time = tonumber(ARGV[2])\n" + "local current = redis.call('get', key);\n" + "if current and tonumber(current) > count then\n" + " return tonumber(current);\n" + "end\n" + "current = redis.call('incr', key)\n" + "if tonumber(current) == 1 then\n" + " redis.call('expire', key, time)\n" + "end\n" + "return tonumber(current);"; |
| | | } |
| | | } |