initial commit: lottery 项目集(三工程统一管理)
- apps/lotteryServer, lotteryCapture, lotteryOpen 三个业务工程 - 忽略 archive/, tools/, infra/data/ 大目录与敏感配置文件 - 移除 lotteryServer 原嵌套 git,并入顶层统一管理
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装载并执行Lua Script,
|
||||
*
|
||||
* 如果服务器上因为集群多台服务器或重启等原因没有装载script,会自动重新装载后重试。
|
||||
*
|
||||
* 因为涉及到的key未知,暂时不支持Sharding。
|
||||
*/
|
||||
public class JedisScriptExecutor {
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisScriptExecutor.class);
|
||||
|
||||
private JedisTemplate jedisTemplate;
|
||||
|
||||
private String script;
|
||||
private String sha1;
|
||||
|
||||
public JedisScriptExecutor(JedisPool jedisPool) {
|
||||
this.jedisTemplate = new JedisTemplate(jedisPool);
|
||||
}
|
||||
|
||||
public JedisScriptExecutor(JedisTemplate jedisTemplate) {
|
||||
this.jedisTemplate = jedisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 装载Lua Script。
|
||||
* 如果Script出错,抛出JedisDataException。
|
||||
*/
|
||||
public void load(final String scriptContent) throws JedisDataException {
|
||||
sha1 = jedisTemplate.execute(new JedisTemplate.JedisAction<String>() {
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.scriptLoad(scriptContent);
|
||||
}
|
||||
});
|
||||
script = scriptContent;
|
||||
|
||||
logger.debug("Script \"{}\" had been loaded as {}", scriptContent, sha1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件加载Lua Script, 文件路径格式为Spring Resource的格式.
|
||||
*/
|
||||
public void loadFromFile(final String scriptPath) throws JedisDataException {
|
||||
String scriptContent;
|
||||
try {
|
||||
Resource resource = new DefaultResourceLoader().getResource(scriptPath);
|
||||
scriptContent = FileUtils.readFileToString(resource.getFile(), "UTF-8");
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(scriptPath + " is not exist.", e);
|
||||
}
|
||||
|
||||
load(scriptContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
|
||||
* keys与args不允许为null.
|
||||
*/
|
||||
public Object execute(final String[] keys, final String[] args) throws IllegalArgumentException {
|
||||
Assert.notNull(keys, "keys can't be null.");
|
||||
Assert.notNull(args, "args can't be null.");
|
||||
return execute(Arrays.asList(keys), Arrays.asList(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
|
||||
* keys与args不允许为null.
|
||||
*/
|
||||
public Object execute(final List<String> keys, final List<String> args) throws IllegalArgumentException {
|
||||
Assert.notNull(keys, "keys can't be null.");
|
||||
Assert.notNull(args, "args can't be null.");
|
||||
|
||||
return jedisTemplate.execute(new JedisTemplate.JedisAction<Object>() {
|
||||
public Object action(Jedis jedis) {
|
||||
try {
|
||||
return jedis.evalsha(sha1, keys, args);
|
||||
} catch (JedisDataException e) {
|
||||
logger.warn(
|
||||
"Script {} is not loaded in server yet or the script is wrong, try to reload and run it again.",
|
||||
script, e);
|
||||
return jedis.eval(script, keys, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import redis.clients.jedis.Tuple;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
import redis.clients.util.Hashing;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* JedisShardTemplate is the JedisTemplate, which has key sharding feature.
|
||||
*
|
||||
* Pass more than one JedisPool to the it, it will calculate which jedisPool will handle the key. If
|
||||
* only one jedisPool passed, it won't do the calculation, so please use JedisShardedTemplate by default.
|
||||
*
|
||||
* But it doesn't support multi-key actions by default, like:
|
||||
* 1. Pipelined and Transaction process multi-keys
|
||||
* 2. Methods in @redis.clients.jedis.MultiKeyCommands like mget, rpoplpush....
|
||||
*
|
||||
* To support them, please use a common sharding key relate to these keys when invoke the APIs.
|
||||
*/
|
||||
public class JedisShardedTemplate {
|
||||
|
||||
private final Hashing algo = Hashing.MURMUR_HASH;
|
||||
private TreeMap<Long, JedisTemplate> nodes = new TreeMap<Long, JedisTemplate>();
|
||||
private JedisTemplate singleTemplate = null;
|
||||
|
||||
public JedisShardedTemplate(JedisPool... jedisPools) {
|
||||
if (jedisPools.length == 1) {
|
||||
singleTemplate = new JedisTemplate(jedisPools[0]);
|
||||
} else {
|
||||
initNodes(jedisPools);
|
||||
}
|
||||
}
|
||||
|
||||
public JedisShardedTemplate(List<JedisPool> jedisPools) {
|
||||
this(jedisPools.toArray(new JedisPool[jedisPools.size()]));
|
||||
}
|
||||
|
||||
private void initNodes(JedisPool... jedisPools) {
|
||||
for (int i = 0; i != jedisPools.length; i++) {
|
||||
// more entry the make the hash ring be more balance
|
||||
for (int n = 0; n < 128; n++) {
|
||||
final JedisPool jedisPool = jedisPools[i];
|
||||
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), new JedisTemplate(jedisPool));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the key and get the jedisTemplate from the hash ring. Get idea from Jedis's Sharded.java
|
||||
*/
|
||||
public JedisTemplate getShard(String key) {
|
||||
if (singleTemplate != null) {
|
||||
return singleTemplate;
|
||||
}
|
||||
|
||||
SortedMap<Long, JedisTemplate> tail = nodes.tailMap(algo.hash(key));
|
||||
if (tail.isEmpty()) {
|
||||
// the last node, back to first.
|
||||
return nodes.get(nodes.firstKey());
|
||||
}
|
||||
return tail.get(tail.firstKey());
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the action.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public <T> T execute(String key, JedisTemplate.JedisAction<T> jedisAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.execute(jedisAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the action.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public void execute(String key, JedisTemplate.JedisActionNoResult jedisAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.execute(jedisAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the pipeline.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public List<Object> execute(String key, JedisTemplate.PipelineAction pipelineAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.execute(pipelineAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the pipeline.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public void execute(String key, JedisTemplate.PipelineActionNoResult pipelineAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.execute(pipelineAction);
|
||||
}
|
||||
|
||||
// / Common Actions ///
|
||||
|
||||
public Boolean del(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.del(key);
|
||||
}
|
||||
|
||||
public Boolean del(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.del(key);
|
||||
}
|
||||
|
||||
// / String Actions ///
|
||||
|
||||
public String get(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.get(key);
|
||||
}
|
||||
|
||||
public String get(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.get(key);
|
||||
}
|
||||
|
||||
public Long getAsLong(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getAsLong(key);
|
||||
}
|
||||
|
||||
public Long getAsLong(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getAsLong(key);
|
||||
}
|
||||
|
||||
public Integer getAsInt(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getAsInt(key);
|
||||
}
|
||||
|
||||
public Integer getAsInt(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getAsInt(key);
|
||||
}
|
||||
|
||||
public void set(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.set(key, value);
|
||||
}
|
||||
|
||||
public void set(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.set(key, value);
|
||||
}
|
||||
|
||||
public void setex(final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.setex(key, value, seconds);
|
||||
}
|
||||
|
||||
public void setex(final String shardingKey, final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.setex(key, value, seconds);
|
||||
}
|
||||
|
||||
public Boolean setnx(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.setnx(key, value);
|
||||
}
|
||||
|
||||
public Boolean setnx(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.setnx(key, value);
|
||||
}
|
||||
|
||||
public Boolean setnxex(final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.setnxex(key, value, seconds);
|
||||
}
|
||||
|
||||
public Boolean setnxex(final String shardingKey, final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.setnxex(key, value, seconds);
|
||||
}
|
||||
|
||||
public String getSet(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getSet(key, value);
|
||||
}
|
||||
|
||||
public String getSet(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getSet(key, value);
|
||||
}
|
||||
|
||||
public Long incr(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incr(key);
|
||||
}
|
||||
|
||||
public Long incr(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incr(key);
|
||||
}
|
||||
|
||||
public Long incrBy(final String key, final Long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incrBy(key, increment);
|
||||
}
|
||||
|
||||
public Long incrBy(final String shardingKey, final String key, final Long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incrBy(key, increment);
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String key, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incrByFloat(key, increment);
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String shardingKey, final String key, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incrByFloat(key, increment);
|
||||
}
|
||||
|
||||
public Long decr(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.decr(key);
|
||||
}
|
||||
|
||||
public Long decr(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.decr(key);
|
||||
}
|
||||
|
||||
public Long decrBy(final String key, final Long decrement) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.decrBy(key, decrement);
|
||||
}
|
||||
|
||||
public Long decrBy(final String shardingKey, final String key, final Long decrement) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.decrBy(key, decrement);
|
||||
}
|
||||
|
||||
// / Hash Actions ///
|
||||
|
||||
public String hget(final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hget(key, field);
|
||||
}
|
||||
|
||||
public String hget(final String shardingKey, final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hmget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String[] fields) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hmget(key, fields);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String shardingKey, final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hmget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String shardingKey, final String key, final String[] fields) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hmget(key, fields);
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hgetAll(key);
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hgetAll(key);
|
||||
}
|
||||
|
||||
public void hset(final String key, final String field, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.hset(key, field, value);
|
||||
}
|
||||
|
||||
public void hset(final String shardingKey, final String key, final String field, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.hset(key, field, value);
|
||||
}
|
||||
|
||||
public void hmset(final String key, final Map<String, String> map) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.hmset(key, map);
|
||||
}
|
||||
|
||||
public void hmset(final String shardingKey, final String key, final Map<String, String> map) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.hmset(key, map);
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String key, final String fieldName, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hsetnx(key, fieldName, value);
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String shardingKey, final String key, final String fieldName, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hsetnx(key, fieldName, value);
|
||||
}
|
||||
|
||||
public Long hincrBy(final String key, final String fieldName, final long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Long hincrBy(final String shardingKey, final String key, final String fieldName, final long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String shardingKey, final String key, final String fieldName,
|
||||
final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String fieldsName) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hdel(key, fieldsName);
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String[] fieldsNames) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hdel(key, fieldsNames);
|
||||
}
|
||||
|
||||
public Long hdel(final String shardingKey, final String key, final String fieldsName) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hdel(key, fieldsName);
|
||||
}
|
||||
|
||||
public Long hdel(final String shardingKey, final String key, final String[] fieldsNames) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hdel(key, fieldsNames);
|
||||
}
|
||||
|
||||
public Boolean hexists(final String key, final String fieldName) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hexists(key, fieldName);
|
||||
}
|
||||
|
||||
public Boolean hexists(final String shardingKey, final String key, final String fieldName) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hexists(key, fieldName);
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hkeys(key);
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hkeys(key);
|
||||
}
|
||||
|
||||
public Long hlen(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hlen(key);
|
||||
}
|
||||
|
||||
public Long hlen(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hlen(key);
|
||||
}
|
||||
|
||||
// / List Actions ///
|
||||
|
||||
public Long lpush(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lpush(key, value);
|
||||
}
|
||||
|
||||
public Long lpush(final String key, final String[] values) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lpush(key, values);
|
||||
}
|
||||
|
||||
public Long lpush(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lpush(key, value);
|
||||
}
|
||||
|
||||
public Long lpush(final String shardingKey, final String key, final String[] values) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lpush(key, values);
|
||||
}
|
||||
|
||||
public String rpop(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.rpop(key);
|
||||
}
|
||||
|
||||
public String rpop(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.rpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.brpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.brpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final int timeout, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.brpop(timeout, key);
|
||||
}
|
||||
|
||||
public String brpop(final String shardingKey, final int timeout, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.brpop(timeout, key);
|
||||
}
|
||||
|
||||
public Long llen(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.llen(key);
|
||||
}
|
||||
|
||||
public Long llen(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.llen(key);
|
||||
}
|
||||
|
||||
public String lindex(final String key, final long index) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lindex(key, index);
|
||||
}
|
||||
|
||||
public String lindex(final String shardingKey, final String key, final long index) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lindex(key, index);
|
||||
}
|
||||
|
||||
public List<String> lrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lrange(key, start, end);
|
||||
}
|
||||
|
||||
public List<String> lrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lrange(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrim(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.ltrim(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrim(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.ltrim(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String key, final int size) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.ltrimFromLeft(key, size);
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String shardingKey, final String key, final int size) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.ltrimFromLeft(key, size);
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lremFirst(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lremFirst(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lremAll(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lremAll(key, value);
|
||||
}
|
||||
|
||||
// / Set Actions ///
|
||||
public Boolean sadd(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.sadd(key, member);
|
||||
}
|
||||
|
||||
public Boolean sadd(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.sadd(key, member);
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.smembers(key);
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.smembers(key);
|
||||
}
|
||||
|
||||
// / Sorted Set Actions ///
|
||||
|
||||
public Boolean zadd(final String key, final double score, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zadd(key, score, member);
|
||||
}
|
||||
|
||||
public Boolean zadd(final String shardingKey, final String key, final double score, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zadd(key, score, member);
|
||||
}
|
||||
|
||||
public Double zscore(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zscore(key, member);
|
||||
}
|
||||
|
||||
public Double zscore(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zscore(key, member);
|
||||
}
|
||||
|
||||
public Long zrank(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrank(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrevrank(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrevrank(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrank(key, member);
|
||||
}
|
||||
|
||||
public Long zcount(final String key, final double start, final double end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zcount(key, start, end);
|
||||
}
|
||||
|
||||
public Long zcount(final String shardingKey, final String key, final double start, final double end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zcount(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String shardingKey, final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String shardingKey, final String key, final double min,
|
||||
final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String shardingKey, final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String shardingKey, final String key, final double max,
|
||||
final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
|
||||
public Boolean zrem(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrem(key, member);
|
||||
}
|
||||
|
||||
public Boolean zrem(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrem(key, member);
|
||||
}
|
||||
|
||||
public Long zremByScore(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zremByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Long zremByScore(final String shardingKey, final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zremByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Long zremByRank(final String key, final long start, final long end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zremByRank(key, start, end);
|
||||
}
|
||||
|
||||
public Long zremByRank(final String shardingKey, final String key, final long start, final long end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zremByRank(key, start, end);
|
||||
}
|
||||
|
||||
public Long zcard(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zcard(key);
|
||||
}
|
||||
|
||||
public Long zcard(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zcard(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,893 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.Tuple;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* JedisTemplate 提供了一个template方法,负责对Jedis连接的获取与归还。
|
||||
* JedisAction<T> 和 JedisActionNoResult两种回调接口,适用于有无返回值两种情况。
|
||||
* PipelineAction 与 PipelineActionResult两种接口,适合于pipeline中批量传输命令的情况。
|
||||
*
|
||||
* 同时提供一些JedisOperation中定义的 最常用函数的封装, 如get/set/zadd等。
|
||||
*/
|
||||
public class JedisTemplate {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisTemplate.class);
|
||||
|
||||
private JedisPool jedisPool;
|
||||
|
||||
public JedisTemplate(JedisPool jedisPool) {
|
||||
this.jedisPool = jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template.
|
||||
*/
|
||||
public interface JedisAction<T> {
|
||||
T action(Jedis jedis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template without result.
|
||||
*/
|
||||
public interface JedisActionNoResult {
|
||||
void action(Jedis jedis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template.
|
||||
*/
|
||||
public interface PipelineAction {
|
||||
List<Object> action(Pipeline Pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template without result.
|
||||
*/
|
||||
public interface PipelineActionNoResult {
|
||||
void action(Pipeline Pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action with result.
|
||||
*/
|
||||
public <T> T execute(JedisAction<T> jedisAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
return jedisAction.action(jedis);
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action without result.
|
||||
*/
|
||||
public void execute(JedisActionNoResult jedisAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
jedisAction.action(jedis);
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action with result in pipeline.
|
||||
*/
|
||||
public List<Object> execute(PipelineAction pipelineAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipelineAction.action(pipeline);
|
||||
return pipeline.syncAndReturnAll();
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action without result in pipeline.
|
||||
*/
|
||||
public void execute(PipelineActionNoResult pipelineAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipelineAction.action(pipeline);
|
||||
pipeline.sync();
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal JedisPool.
|
||||
*/
|
||||
public JedisPool getJedisPool() {
|
||||
return jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle jedisException, write log and return whether the connection is broken.
|
||||
*/
|
||||
protected boolean handleJedisException(JedisException jedisException) {
|
||||
if (jedisException instanceof JedisConnectionException) {
|
||||
logger.error("Redis connection " + jedisPool.getAddress() + " lost.", jedisException);
|
||||
} else if (jedisException instanceof JedisDataException) {
|
||||
if ((jedisException.getMessage() != null) && (jedisException.getMessage().indexOf("READONLY") != -1)) {
|
||||
logger.error("Redis connection " + jedisPool.getAddress() + " are read-only slave.", jedisException);
|
||||
} else {
|
||||
// dataException, isBroken=false
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
logger.error("Jedis exception happen.", jedisException);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return jedis connection to the pool, call different return methods depends on the conectionBroken status.
|
||||
*/
|
||||
protected void closeResource(Jedis jedis, boolean conectionBroken) {
|
||||
try {
|
||||
if (conectionBroken) {
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
} else {
|
||||
jedisPool.returnResource(jedis);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("return back jedis failed, will fore close the jedis.", e);
|
||||
JedisUtils.destroyJedis(jedis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// / Common Actions ///
|
||||
|
||||
/**
|
||||
* Remove the specified keys. If a given key does not exist no operation is
|
||||
* performed for this key.
|
||||
*
|
||||
* return false if one of the key is not exist.
|
||||
*/
|
||||
public Boolean del(final String... keys) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.del(keys) == keys.length ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void flushDB() {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.flushDB();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / String Actions ///
|
||||
|
||||
/**
|
||||
* Get the value of the specified key. If the key does not exist null is
|
||||
* returned. If the value stored at key is not a string an error is returned
|
||||
* because GET can only handle string values.
|
||||
*/
|
||||
public String get(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.get(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> keys(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.keys(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Long.If the key does not exist null is returned.
|
||||
*/
|
||||
public Long getAsLong(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Long.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Integer.If the key does not exist null is returned.
|
||||
*/
|
||||
public Integer getAsInt(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Integer.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Double.If the key does not exist null is returned.
|
||||
*/
|
||||
public Double getAsDouble(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Double.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the values of all the specified keys. If one or more keys dont exist
|
||||
* or is not of type String, a 'nil' value is returned instead of the value
|
||||
* of the specified key, but the operation never fails.
|
||||
*/
|
||||
public List<String> mget(final String... keys) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.mget(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the string value as value of the key.
|
||||
* The string can't be longer than 1073741824 bytes (1 GB).
|
||||
*/
|
||||
public void set(final String key, final String value) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.set(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void expire(final String key, final int seconds) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.expire(key, seconds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The command is exactly equivalent to the following group of commands: {@link #set(String, String) SET} +
|
||||
* {@link #expire(String, int) EXPIRE}.
|
||||
* The operation is atomic.
|
||||
*/
|
||||
public void setex(final String key, final String value, final int seconds) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.setex(key, seconds, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* SETNX works exactly like {@link #setNX(String, String) SET} with the only
|
||||
* difference that if the key already exists no operation is performed.
|
||||
* SETNX actually means "SET if Not eXists".
|
||||
*
|
||||
* return true if the key was set.
|
||||
*/
|
||||
public Boolean setnx(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.setnx(key, value) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The command is exactly equivalent to the following group of commands: {@link #setex(String, String, int) SETEX} +
|
||||
* {@link #sexnx(String, String) SETNX}.
|
||||
* The operation is atomic.
|
||||
*/
|
||||
public Boolean setnxex(final String key, final String value, final int seconds) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
String result = jedis.set(key, value, "NX", "EX", seconds);
|
||||
return JedisUtils.isStatusOk(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* GETSET is an atomic set this value and return the old value command. Set
|
||||
* key to the string value and return the old value stored at key. The
|
||||
* string can't be longer than 1073741824 bytes (1 GB).
|
||||
*/
|
||||
public String getSet(final String key, final String value) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.getSet(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the number stored at key by one. If the key does not exist or
|
||||
* contains a value of a wrong type, set the key to the value of "0" before
|
||||
* to perform the increment operation.
|
||||
* <p>
|
||||
* INCR commands are limited to 64 bit signed integers.
|
||||
* <p>
|
||||
* Note: this is actually a string operation, that is, in Redis there are not "integer" types. Simply the string
|
||||
* stored at the key is parsed as a base 10 64 bit signed integer, incremented, and then converted back as a string.
|
||||
*
|
||||
* @return Integer reply, this commands will reply with the new value of key
|
||||
* after the increment.
|
||||
*/
|
||||
public Long incr(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.incr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long incrBy(final String key, final long increment) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.incrBy(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String key, final double increment) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.incrByFloat(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the number stored at key by one. If the key does not exist or
|
||||
* contains a value of a wrong type, set the key to the value of "0" before
|
||||
* to perform the decrement operation.
|
||||
*/
|
||||
public Long decr(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.decr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long decrBy(final String key, final long decrement) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.decrBy(key, decrement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Hash Actions ///
|
||||
/**
|
||||
* If key holds a hash, retrieve the value associated to the specified
|
||||
* field.
|
||||
* <p>
|
||||
* If the field is not found or the key does not exist, a special 'nil' value is returned.
|
||||
*/
|
||||
public String hget(final String key, final String fieldName) {
|
||||
return execute(new JedisAction<String>() {
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.hget(key, fieldName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String... fieldsNames) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.hmget(key, fieldsNames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String key) {
|
||||
return execute(new JedisAction<Map<String, String>>() {
|
||||
@Override
|
||||
public Map<String, String> action(Jedis jedis) {
|
||||
return jedis.hgetAll(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hset(final String key, final String fieldName, final String value) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.hset(key, fieldName, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hmset(final String key, final Map<String, String> map) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.hmset(key, map);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String key, final String fieldName, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.hsetnx(key, fieldName, value) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hincrBy(final String key, final String fieldName, final long increment) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String... fieldsNames) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hdel(key, fieldsNames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean hexists(final String key, final String fieldName) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.hexists(key, fieldName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.hkeys(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hlen(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hlen(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / List Actions ///
|
||||
|
||||
public Long lpush(final String key, final String... values) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.lpush(key, values);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long rpush(final String key, final String... values) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.rpush(key, values);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String rpop(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.rpop(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String brpop(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
List<String> nameValuePair = jedis.brpop(key);
|
||||
if (nameValuePair != null) {
|
||||
return nameValuePair.get(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String brpop(final int timeout, final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
List<String> nameValuePair = jedis.brpop(timeout, key);
|
||||
if (nameValuePair != null) {
|
||||
return nameValuePair.get(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Not support for sharding.
|
||||
*/
|
||||
public String rpoplpush(final String sourceKey, final String destinationKey) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.rpoplpush(sourceKey, destinationKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Not support for sharding.
|
||||
*/
|
||||
public String brpoplpush(final String source, final String destination, final int timeout) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.brpoplpush(source, destination, timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long llen(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.llen(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String lindex(final String key, final long index) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.lindex(key, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> lrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.lrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ltrim(final String key, final int start, final int end) {
|
||||
execute(new JedisActionNoResult() {
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.ltrim(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String key, final int size) {
|
||||
execute(new JedisActionNoResult() {
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.ltrim(key, 0, size - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
Long count = jedis.lrem(key, 1, value);
|
||||
return (count == 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
Long count = jedis.lrem(key, 0, value);
|
||||
return (count > 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Set Actions ///
|
||||
public Boolean sadd(final String key, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.sadd(key, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.smembers(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Ordered Set Actions ///
|
||||
/**
|
||||
* return true for add new element, false for only update the score.
|
||||
*/
|
||||
public Boolean zadd(final String key, final double score, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.zadd(key, score, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double zscore(final String key, final String member) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.zscore(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zrank(final String key, final String member) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zrank(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zrevrank(final String key, final String member) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zrevrank(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zcount(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zcount(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrangeWithScores(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrevrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrangeByScore(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean zrem(final String key, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.zrem(key, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zremByScore(final String key, final double start, final double end) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zremrangeByScore(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zremByRank(final String key, final long start, final long end) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zremrangeByRank(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zcard(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zcard(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
public class JedisUtils {
|
||||
|
||||
private static final String OK_CODE = "OK";
|
||||
private static final String OK_MULTI_CODE = "+OK";
|
||||
|
||||
/**
|
||||
* 判断 返回值是否ok.
|
||||
*/
|
||||
public static boolean isStatusOk(String status) {
|
||||
return (status != null) && (OK_CODE.equals(status) || OK_MULTI_CODE.equals(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在Pool以外强行销毁Jedis.
|
||||
*/
|
||||
public static void destroyJedis(Jedis jedis) {
|
||||
if ((jedis != null) && jedis.isConnected()) {
|
||||
try {
|
||||
try {
|
||||
jedis.quit();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
jedis.disconnect();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping the jedis instance, return true is the result is PONG.
|
||||
*/
|
||||
public static boolean ping(JedisPool pool) {
|
||||
JedisTemplate template = new JedisTemplate(pool);
|
||||
try {
|
||||
String result = template.execute(new JedisTemplate.JedisAction<String>() {
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.ping();
|
||||
}
|
||||
});
|
||||
return (result != null) && result.equals("PONG");
|
||||
} catch (JedisException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
/**
|
||||
* All information for redis connection.
|
||||
*/
|
||||
public class ConnectionInfo {
|
||||
|
||||
public static final String DEFAULT_PASSWORD = null;
|
||||
|
||||
private int database = Protocol.DEFAULT_DATABASE;
|
||||
private String password = DEFAULT_PASSWORD;
|
||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
|
||||
public ConnectionInfo() {
|
||||
}
|
||||
|
||||
public ConnectionInfo(int database, String password, int timeout) {
|
||||
this.timeout = timeout;
|
||||
if (password != null && password.length() > 0) {
|
||||
this.password = password;
|
||||
}
|
||||
else {
|
||||
this.password = DEFAULT_PASSWORD;
|
||||
}
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public int getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(int database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if (password != null && password.length() > 0) {
|
||||
this.password = password;
|
||||
}
|
||||
else {
|
||||
this.password = DEFAULT_PASSWORD;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectionInfo [database=" + database + ", password=" + password + ", timeout=" + timeout + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
* Pool which connect to redis instance directly.
|
||||
*/
|
||||
public class JedisDirectPool extends JedisPool {
|
||||
|
||||
public JedisDirectPool(HostAndPort address, JedisPoolConfig config) {
|
||||
initInternalPool(address, new ConnectionInfo(), config);
|
||||
}
|
||||
|
||||
public JedisDirectPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
initInternalPool(address, connectionInfo, config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.PooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import redis.clients.jedis.BinaryJedis;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
* Copy from redis.clients.jedis.JedisFactory, because it is not a public class.
|
||||
*/
|
||||
public class JedisFactory implements PooledObjectFactory<Jedis> {
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final int timeout;
|
||||
private final String password;
|
||||
private final int database;
|
||||
private final String clientName;
|
||||
|
||||
public JedisFactory(final String host, final int port, final int timeout, final String password, final int database) {
|
||||
this(host, port, timeout, password, database, null);
|
||||
}
|
||||
|
||||
public JedisFactory(final String host, final int port, final int timeout, final String password,
|
||||
final int database, final String clientName) {
|
||||
super();
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.timeout = timeout;
|
||||
this.password = password;
|
||||
this.database = database;
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
if (jedis.getDB() != database) {
|
||||
jedis.select(database);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
if (jedis.isConnected()) {
|
||||
try {
|
||||
try {
|
||||
jedis.quit();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
jedis.disconnect();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<Jedis> makeObject() throws Exception {
|
||||
final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
|
||||
|
||||
jedis.connect();
|
||||
if (null != this.password) {
|
||||
jedis.auth(this.password);
|
||||
}
|
||||
if (database != 0) {
|
||||
jedis.select(database);
|
||||
}
|
||||
if (clientName != null) {
|
||||
jedis.clientSetname(clientName);
|
||||
}
|
||||
|
||||
return new DefaultPooledObject<Jedis>(jedis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
// TODO maybe should select db 0? Not sure right now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject<Jedis> pooledJedis) {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
try {
|
||||
return jedis.isConnected() && jedis.ping().equals("PONG");
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.util.Pool;
|
||||
|
||||
/**
|
||||
* Jedis Pool base class.
|
||||
*/
|
||||
public abstract class JedisPool extends Pool<Jedis> {
|
||||
|
||||
protected HostAndPort address;
|
||||
|
||||
protected ConnectionInfo connectionInfo;
|
||||
|
||||
/**
|
||||
* Create a JedisPoolConfig with new maxPoolSize becasuse JedisPoolConfig's default maxPoolSize is only 8.
|
||||
* Also reset the idle checking time to 10 minutes, the default value is half minute.
|
||||
* Also rest the max idle to zero, the default value is 8 too.
|
||||
* The default idle time is 60 seconds.
|
||||
*/
|
||||
public static JedisPoolConfig createPoolConfig(int maxPoolSize) {
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
config.setMaxTotal(maxPoolSize);
|
||||
config.setMaxIdle(maxPoolSize);
|
||||
|
||||
config.setTimeBetweenEvictionRunsMillis(600 * 1000);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the internal pool with connection info and pool config.
|
||||
*/
|
||||
protected void initInternalPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
this.address = address;
|
||||
this.connectionInfo = connectionInfo;
|
||||
JedisFactory factory = new JedisFactory(address.getHost(), address.getPort(), connectionInfo.getTimeout(),
|
||||
connectionInfo.getPassword(), connectionInfo.getDatabase());
|
||||
|
||||
internalPool = new GenericObjectPool(factory, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a broken jedis connection back to pool.
|
||||
*/
|
||||
@Override
|
||||
public void returnBrokenResource(final Jedis resource) {
|
||||
if (resource != null) {
|
||||
returnBrokenResourceObject(resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a available jedis connection back to pool.
|
||||
*/
|
||||
@Override
|
||||
public void returnResource(final Jedis resource) {
|
||||
if (resource != null) {
|
||||
resource.resetState();
|
||||
returnResourceObject(resource);
|
||||
}
|
||||
}
|
||||
|
||||
public HostAndPort getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public ConnectionInfo getConnectionInfo() {
|
||||
return connectionInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Build JedisPool smartly。
|
||||
* Depends on masterName whether prefix with "direct:", it will build JedisSentinelPool or JedisDirectPool.
|
||||
*/
|
||||
public class JedisPoolBuilder {
|
||||
|
||||
public static final String DIRECT_POOL_PREFIX = "direct:";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisPoolBuilder.class);
|
||||
|
||||
private String[] sentinelHosts;
|
||||
private int sentinelPort = Protocol.DEFAULT_SENTINEL_PORT;
|
||||
|
||||
private String masterName;
|
||||
private String[] shardedMasterNames;
|
||||
|
||||
private int poolSize = -1;
|
||||
|
||||
private int database = Protocol.DEFAULT_DATABASE;
|
||||
private String password = ConnectionInfo.DEFAULT_PASSWORD;
|
||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
|
||||
public JedisPoolBuilder setHosts(String[] hosts) {
|
||||
this.sentinelHosts = hosts;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setHosts(String hosts) {
|
||||
if (hosts != null) {
|
||||
this.sentinelHosts = hosts.split(",");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPort(int port) {
|
||||
this.sentinelPort = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setMasterName(String masterName) {
|
||||
this.masterName = masterName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setShardedMasterNames(String[] shardedMasterNames) {
|
||||
this.shardedMasterNames = shardedMasterNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setShardedMasterNames(String shardedMasterNames) {
|
||||
if (shardedMasterNames != null) {
|
||||
this.shardedMasterNames = shardedMasterNames.split(",");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setDirectHostAndPort(String host, String port) {
|
||||
this.masterName = host + ":" + port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPoolSize(int poolSize) {
|
||||
this.poolSize = poolSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setDatabase(int database) {
|
||||
this.database = database;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPool buildPool() {
|
||||
|
||||
if ((masterName == null) || "".equals(masterName)) {
|
||||
throw new IllegalArgumentException("masterName is null or empty");
|
||||
}
|
||||
|
||||
if (poolSize < 1) {
|
||||
throw new IllegalArgumentException("poolSize is less then one");
|
||||
}
|
||||
|
||||
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
|
||||
|
||||
if (isDirect(masterName)) {
|
||||
return buildDirectPool(masterName, connectionInfo, config);
|
||||
} else {
|
||||
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
|
||||
throw new IllegalArgumentException("sentinelHosts is null or empty");
|
||||
}
|
||||
return buildSentinelPool(masterName, connectionInfo, config);
|
||||
}
|
||||
}
|
||||
|
||||
public List<JedisPool> buildShardedPools() {
|
||||
|
||||
if ((shardedMasterNames == null) || (shardedMasterNames.length == 0) || "".equals(shardedMasterNames[0])) {
|
||||
throw new IllegalArgumentException("shardedMasterNames is null or empty");
|
||||
}
|
||||
|
||||
if (poolSize < 1) {
|
||||
throw new IllegalArgumentException("poolSize is less then one");
|
||||
}
|
||||
|
||||
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
|
||||
|
||||
List<JedisPool> jedisPools = new ArrayList<JedisPool>();
|
||||
|
||||
if (isDirect(shardedMasterNames[0])) {
|
||||
for (String theMasterName : shardedMasterNames) {
|
||||
jedisPools.add(buildDirectPool(theMasterName, connectionInfo, config));
|
||||
}
|
||||
} else {
|
||||
|
||||
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
|
||||
throw new IllegalArgumentException("sentinelHosts is null or empty");
|
||||
}
|
||||
|
||||
for (String theMasterName : shardedMasterNames) {
|
||||
jedisPools.add(buildSentinelPool(theMasterName, connectionInfo, config));
|
||||
}
|
||||
}
|
||||
return jedisPools;
|
||||
}
|
||||
|
||||
private JedisPool buildDirectPool(String directMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
String hostPortStr = directMasterName.substring(directMasterName.indexOf(":") + 1, directMasterName.length());
|
||||
String[] hostPort = hostPortStr.split(":");
|
||||
|
||||
logger.info("Building JedisDirectPool, on redis server " + hostPort[0] + " ,sentinelPort is " + hostPort[1]);
|
||||
|
||||
HostAndPort masterAddress = new HostAndPort(hostPort[0], Integer.parseInt(hostPort[1]));
|
||||
return new JedisDirectPool(masterAddress, config);
|
||||
}
|
||||
|
||||
private JedisPool buildSentinelPool(String sentinelMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
logger.info("Building JedisSentinelPool, on sentinel sentinelHosts:" + Arrays.toString(sentinelHosts)
|
||||
+ " ,sentinelPort is " + sentinelPort + " ,masterName is " + sentinelMasterName);
|
||||
|
||||
HostAndPort[] sentinelAddress = new HostAndPort[sentinelHosts.length];
|
||||
for (int i = 0; i < sentinelHosts.length; i++) {
|
||||
sentinelAddress[i] = new HostAndPort(sentinelHosts[i], sentinelPort);
|
||||
}
|
||||
|
||||
return new JedisSentinelPool(sentinelAddress, sentinelMasterName, connectionInfo, config);
|
||||
}
|
||||
|
||||
private static boolean isDirect(String masterName) {
|
||||
return masterName.startsWith(DIRECT_POOL_PREFIX);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import javautils.redis.JedisTemplate;
|
||||
import javautils.redis.JedisUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Pool which to get redis master address get from sentinel instances.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pool which to get redis master address get from sentinel instances.
|
||||
*/
|
||||
public final class JedisSentinelPool extends JedisPool {
|
||||
|
||||
private static final String NO_ADDRESS_YET = "I dont know because no sentinel up";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisSentinelPool.class);
|
||||
|
||||
private List<JedisPool> sentinelPools = new ArrayList<JedisPool>();
|
||||
private MasterSwitchListener masterSwitchListener;
|
||||
|
||||
private String masterName;
|
||||
private JedisPoolConfig masterPoolConfig;
|
||||
private ConnectionInfo masterConnectionInfo;
|
||||
private CountDownLatch poolInit = new CountDownLatch(1);
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>JedisSentinelPool</code>.
|
||||
*
|
||||
* All parameters can be null or empty.
|
||||
*
|
||||
* @param sentinelAddresses Array of HostAndPort to sentinel instances.
|
||||
* @param masterName One sentinel can monitor several redis master-slave pair, use master name to identify them.
|
||||
* @param masterConnectionInfo The the other information like password,timeout.
|
||||
* @param masterPoolConfig Configuration of redis pool.
|
||||
*
|
||||
*/
|
||||
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, ConnectionInfo masterConnectionInfo,
|
||||
JedisPoolConfig masterPoolConfig) {
|
||||
// sentinelAddresses
|
||||
assertArgument(((sentinelAddresses == null) || (sentinelAddresses.length == 0)), "seintinelInfos is not set");
|
||||
|
||||
for (HostAndPort sentinelInfo : sentinelAddresses) {
|
||||
JedisPool sentinelPool = new JedisDirectPool(sentinelInfo, new JedisPoolConfig());
|
||||
sentinelPools.add(sentinelPool);
|
||||
}
|
||||
|
||||
// masterConnectionInfo
|
||||
assertArgument(masterConnectionInfo == null, "masterConnectionInfo is not set");
|
||||
this.masterConnectionInfo = masterConnectionInfo;
|
||||
|
||||
// masterName
|
||||
assertArgument(((masterName == null) || masterName.isEmpty()), "masterName is not set");
|
||||
this.masterName = masterName;
|
||||
|
||||
// poolConfig
|
||||
assertArgument(masterPoolConfig == null, "masterPoolConfig is not set");
|
||||
this.masterPoolConfig = masterPoolConfig;
|
||||
|
||||
// Start MasterSwitchListener thread ,internal poll will be start in the thread
|
||||
masterSwitchListener = new MasterSwitchListener();
|
||||
masterSwitchListener.start();
|
||||
|
||||
try {
|
||||
if (!poolInit.await(5, TimeUnit.SECONDS)) {
|
||||
logger.warn("the sentiel pool can't not init in 5 seconds");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, JedisPoolConfig masterPoolConfig) {
|
||||
this(sentinelAddresses, masterName, new ConnectionInfo(), masterPoolConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// shutdown the listener thread
|
||||
masterSwitchListener.shutdown();
|
||||
|
||||
// destroy sentinel pools
|
||||
for (JedisPool sentinel : sentinelPools) {
|
||||
sentinel.destroy();
|
||||
}
|
||||
|
||||
// destroy redis pool
|
||||
destroyInternelPool();
|
||||
|
||||
// wait for the masterSwitchListener thread finish
|
||||
try {
|
||||
logger.info("Waiting for MasterSwitchListener thread finish");
|
||||
masterSwitchListener.join();
|
||||
logger.info("MasterSwitchListener thread finished");
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
protected void destroyInternelPool() {
|
||||
closeInternalPool();
|
||||
|
||||
address = null;
|
||||
connectionInfo = null;
|
||||
internalPool = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the argurment, throw IllegalArgumentException if the expression is true.
|
||||
*/
|
||||
private static void assertArgument(boolean expression, String message) {
|
||||
if (expression) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
// for test
|
||||
public MasterSwitchListener getMasterSwitchListener() {
|
||||
return masterSwitchListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener thread to listen master switch message from sentinel.
|
||||
*/
|
||||
public class MasterSwitchListener extends Thread {
|
||||
public static final String THREAD_NAME_PREFIX = "MasterSwitchListener-";
|
||||
|
||||
private JedisPubSub subscriber;
|
||||
private JedisPool sentinelPool;
|
||||
private Jedis sentinelJedis;
|
||||
private AtomicBoolean running = new AtomicBoolean(true);
|
||||
private HostAndPort previousMasterAddress;
|
||||
|
||||
public MasterSwitchListener() {
|
||||
super(THREAD_NAME_PREFIX + masterName);
|
||||
}
|
||||
|
||||
// stop the blocking subscription and interrupt the thread
|
||||
public void shutdown() {
|
||||
// interrupt the thread
|
||||
running.getAndSet(false);
|
||||
this.interrupt();
|
||||
|
||||
// stop the blocking subscription
|
||||
try {
|
||||
if (subscriber != null) {
|
||||
subscriber.unsubscribe();
|
||||
}
|
||||
} finally {
|
||||
JedisUtils.destroyJedis(sentinelJedis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (running.get()) {
|
||||
try {
|
||||
sentinelPool = pickupSentinel();
|
||||
|
||||
if (sentinelPool != null) {
|
||||
|
||||
HostAndPort masterAddress = queryMasterAddress();
|
||||
|
||||
if ((internalPool != null) && isAddressChange(masterAddress)) {
|
||||
logger.info("The internalPool {} had changed, destroy it now.", previousMasterAddress);
|
||||
destroyInternelPool();
|
||||
}
|
||||
|
||||
if (internalPool == null) {
|
||||
logger.info("The internalPool {} is not init or the address had changed, init it now.",
|
||||
masterAddress);
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
poolInit.countDown();
|
||||
}
|
||||
|
||||
previousMasterAddress = masterAddress;
|
||||
|
||||
sentinelJedis = sentinelPool.getResource();
|
||||
subscriber = new MasterSwitchSubscriber();
|
||||
sentinelJedis.subscribe(subscriber, "+switch-master", "+redirect-to-master");
|
||||
} else {
|
||||
logger.info("All sentinels down, sleep 2 seconds and try to connect again.");
|
||||
// When the system startup but the sentinels not yet, init a urgly address to prevent null point
|
||||
// exception. change the logic later.
|
||||
if (internalPool == null) {
|
||||
HostAndPort masterAddress = new HostAndPort(NO_ADDRESS_YET, 6379);
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
previousMasterAddress = masterAddress;
|
||||
}
|
||||
sleep(2000);
|
||||
}
|
||||
} catch (JedisConnectionException e) {
|
||||
|
||||
if (sentinelJedis != null) {
|
||||
sentinelPool.returnBrokenResource(sentinelJedis);
|
||||
}
|
||||
|
||||
if (running.get()) {
|
||||
logger.error("Lost connection with Sentinel " + sentinelPool.getAddress()
|
||||
+ ", sleep 1 seconds and try to connect other one. ");
|
||||
sleep(1000);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HostAndPort getCurrentMasterAddress() {
|
||||
return previousMasterAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pickup the first available sentinel, if all sentinel down, return null.
|
||||
*/
|
||||
private JedisPool pickupSentinel() {
|
||||
for (JedisPool pool : sentinelPools) {
|
||||
if (JedisUtils.ping(pool)) {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isAddressChange(HostAndPort currentMasterAddress) {
|
||||
if (previousMasterAddress == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !previousMasterAddress.equals(currentMasterAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query master address from sentinel.
|
||||
*/
|
||||
private HostAndPort queryMasterAddress() {
|
||||
JedisTemplate sentinelTemplate = new JedisTemplate(sentinelPool);
|
||||
List<String> address = sentinelTemplate.execute(new JedisTemplate.JedisAction<List<String>>() {
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.sentinelGetMasterAddrByName(masterName);
|
||||
}
|
||||
});
|
||||
|
||||
if ((address == null) || address.isEmpty()) {
|
||||
throw new IllegalArgumentException("Master name " + masterName + " is not in sentinel.conf");
|
||||
}
|
||||
|
||||
return new HostAndPort(address.get(0), Integer.valueOf(address.get(1)));
|
||||
}
|
||||
|
||||
private void sleep(int millseconds) {
|
||||
try {
|
||||
Thread.sleep(millseconds);
|
||||
} catch (InterruptedException e1) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscriber for the master switch message from sentinel and init the new pool.
|
||||
*/
|
||||
private class MasterSwitchSubscriber extends JedisPubSub {
|
||||
@Override
|
||||
public void onMessage(String channel, String message) {
|
||||
// message example: +switch-master: mymaster 127.0.0.1 6379 127.0.0.1 6380
|
||||
// +redirect-to-master default 127.0.0.1 6380 127.0.0.1 6381 (if slave-master fail-over quick enough)
|
||||
logger.info("Sentinel " + sentinelPool.getAddress() + " published: " + message);
|
||||
String[] switchMasterMsg = message.split(" ");
|
||||
// if the master name equals my master name, destroy the old pool and init a new pool
|
||||
if (masterName.equals(switchMasterMsg[0])) {
|
||||
|
||||
HostAndPort masterAddress = new HostAndPort(switchMasterMsg[3],
|
||||
Integer.parseInt(switchMasterMsg[4]));
|
||||
logger.info("Switch master to " + masterAddress);
|
||||
destroyInternelPool();
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
previousMasterAddress = masterAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPMessage(String pattern, String channel, String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(String channel, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnsubscribe(String channel, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPUnsubscribe(String pattern, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPSubscribe(String pattern, int subscribedChannels) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user