import java.net.URI;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.util.JedisURIHelper;
@Slf4j
@Component
public class RedisLogic {
@Autowired
private IConfigPropertyService configPropertyService;
private JedisPool jedisPool;
public static String order_limit = null;
@PostConstruct
public void init() throws Exception {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
URI uri = null;
List<ConfigProperty> redisConfigs = configPropertyService.listConfigPropertyByPropertyTypeNotAll("redis_config");
if (!CollectionUtils.isEmpty(redisConfigs)) {
for (ConfigProperty redisConfig : redisConfigs) {
if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "maxTotal")) {
jedisPoolConfig.setMaxTotal(Integer.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "maxIdle")) {
jedisPoolConfig.setMaxIdle(Integer.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "minIdle")) {
jedisPoolConfig.setMinIdle(Integer.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "maxWaitMillis")) {
jedisPoolConfig.setMaxWaitMillis(Long.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "true")) {
jedisPoolConfig.setLifo(Boolean.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "testOnBorrow")) {
jedisPoolConfig.setTestOnBorrow(Boolean.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "testOnReturn")) {
jedisPoolConfig.setTestOnReturn(Boolean.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "testWhileIdle")) {
jedisPoolConfig.setTestWhileIdle(Boolean.valueOf(redisConfig.getPropertyValue()));
} else if (StringUtils.equalsIgnoreCase(redisConfig.getPropertyKey(), "url")) {
uri = URI.create(redisConfig.getPropertyValue());
}
}
} else {
throw new RuntimeException("请在数据库中配置redis连接参数!");
}
if (JedisURIHelper.isValid(uri)) {
String host = uri.getHost();
int port = uri.getPort();
String password = JedisURIHelper.getPassword(uri);
jedisPool = new JedisPool(jedisPoolConfig, host, port, 2000, password);
}
cacheLuaFile();
}
private void cacheLuaFile() throws Exception {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
order_limit = jedis.scriptLoad(IOUtils.toString(new ClassPathResource("order_limit.lua").getInputStream(), "UTF-8"));
log.info("order_limit={}", order_limit);
} catch (Exception e) {
throw e;
} finally {
returnResource(jedis);
}
}
public boolean orderLimit(String key, String limitKey, String limitValue) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return "true".equals(jedis.evalsha(order_limit, Arrays.asList(key, limitKey), Arrays.asList(limitValue)));
} catch (Exception ex) {
log.error("redis设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期异常:[key={}]" , key, ex);
} finally {
returnResource(jedis);
}
return false;
}
private void returnResource(Jedis jedis) {
if (jedis == null) {
return;
}
try {
jedis.close();
jedis = null;
} catch (Exception e) {
log.error("returnResource error.", e);
}
}
}
local key = KEYS[1]
local key2 = KEYS[2]
local value = ARGV[1]
if redis.call('EXISTS',key) == 0 then
redis.call('INCR',key)
return "true"
else
if tonumber(redis.call('GET',key)) < tonumber(value) then
redis.call('INCR',key)
return "true"
else
if redis.call('EXISTS',key2) == 0 then
redis.call('SET',key2, "true")
end
return "false"
end
end