SpringBoot+Redis+Lua限流

编程

# Redis数据库索引 默认为0

spring.redis.database=0

# Redis地址

spring.redis.host=localhost

# Redis端口 默认6379

spring.redis.port=6379

# Redis服务器连接密码(默认为空)

spring.redis.password=

# 连接池最大连接数(使用负值表示没有限制)

spring.redis.jedis.pool.max-active=8

# 连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.jedis.pool.max-wait=-1

# 连接池中的最大空闲连接

spring.redis.jedis.pool.max-idle=8

# 连接池中的最小空闲连接

spring.redis.jedis.pool.min-idle=0

# 连接超时时间(毫秒)

spring.redis.timeout=10000

4. 新建request_rate_limiter.lua 放到resources下,内容如下

local key = KEYS[1]

redis.log(redis.LOG_WARNING, "tokens_key ", key)

local capacity = tonumber(ARGV[1])

local timestamp = tonumber(ARGV[2])

local id = ARGV[3]

local count = tonumber(redis.call("get", key) or "0")

local allowed = count < capacity

if not allowed then

return { allowed, count }

else

redis.call("setex", key, timestamp, (count + 1))

end

return { allowed, count }

5. redisTemplate类注入

package com.limit.redis;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;

/**

* @Description:

* @author: fang-pc

* @date: 2020年3月12日 下午12:50:38

*/

@Configuration

public class RedisConfig {

@Bean

public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

RedisTemplate<String, Object> template = new RedisTemplate();

template.setConnectionFactory(factory);

FastJsonRedisSerializer<String> serializer = new FastJsonRedisSerializer<>(String.class);

StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

// key采用String的序列化方式

template.setKeySerializer(stringRedisSerializer);

// hash的key也采用String的序列化方式

template.setHashKeySerializer(stringRedisSerializer);

// value序列化方式采用jackson

template.setValueSerializer(serializer);

// hash的value序列化方式采用jackson

template.setHashValueSerializer(serializer);

template.afterPropertiesSet();

return template;

}

}

6.  主要代码

package com.limit.redis;

import java.util.Arrays;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;

import org.springframework.core.io.ClassPathResource;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.script.DefaultRedisScript;

import org.springframework.data.redis.core.script.RedisScript;

import org.springframework.scripting.support.ResourceScriptSource;

import org.springframework.stereotype.Component;

/**

* @Description:

* @author: fang-pc

* @date: 2020年3月12日 上午11:57:56

*/

@Component

public class RateLimiterRunner implements ApplicationRunner{

@Autowired

private RedisTemplate<String, Object> template;

@Override

public void run(ApplicationArguments args) throws Exception {

RedisScript<List<Long>> redisScript = redisScript();

ExecutorService executor = Executors.newFixedThreadPool(20);

for (int i = 0; i < 100; i++) {

executor.submit(() -> {

try {

List<Long> list = template.execute(redisScript, Arrays.asList("user_id_1"), Arrays.asList(5, 2, 1).toArray());

System.out.println(list);

} catch (Exception e) {

e.printStackTrace();

}

});

}

}

private RedisScript<List<Long>> redisScript() {

DefaultRedisScript redisScript = new DefaultRedisScript<>();

redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("concurrent_request_rate_limiter.lua")));

redisScript.setResultType(List.class);

return redisScript;

}

}

7.  注解添加scanBasePackages,启动效果

文章案例只是入门demo

以上是 SpringBoot+Redis+Lua限流 的全部内容, 来源链接: utcz.com/z/514353.html

回到顶部