Redis客户端简单封装

javahongxi edited this page Jan 11, 2019 · 7 revisions
<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
public class ShardedRedisClient implements FactoryBean<ShardedJedisPool>, InitializingBean, DisposableBean {

    private ShardedJedisPool shardedJedisPool;

    private JedisPoolConfig jedisPoolConfig;

    private String address;

    private int timeout = 3000;

    @Override
    public ShardedJedisPool getObject() throws Exception {
        return shardedJedisPool;
    }

    @Override
    public Class<?> getObjectType() {
        return ShardedJedisPool.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<JedisShardInfo> shardInfos = new ArrayList<>();
        String[] addressArr = address.split(",");
        for (String internalAddress : addressArr) {
            String[] infoParams = internalAddress.split(":");
            shardInfos.add(new JedisShardInfo(infoParams[1], Integer.parseInt(infoParams[2]), timeout, infoParams[0]));
        }
        shardedJedisPool = new ShardedJedisPool(jedisPoolConfig, shardInfos);
    }

    @Override
    public void destroy() throws Exception {
        if (shardedJedisPool != null) {
            shardedJedisPool.close();
        }
    }

    public void setJedisPoolConfig(JedisPoolConfig jedisPoolConfig) {
        this.jedisPoolConfig = jedisPoolConfig;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

}
public class RedisClusterClient implements FactoryBean<JedisCluster>, InitializingBean, DisposableBean {

    private JedisCluster jedisCluster;

    private JedisPoolConfig jedisPoolConfig;

    // ip:port,ip:port
    private String address;

    private int timeout = 3000;

    @Override
    public JedisCluster getObject() throws Exception {
        return jedisCluster;
    }

    @Override
    public Class<?> getObjectType() {
        return JedisCluster.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Set<HostAndPort> hostAndPorts = buildHostAndPorts();
        jedisCluster = new JedisCluster(hostAndPorts, timeout, jedisPoolConfig);
    }

    private Set<HostAndPort> buildHostAndPorts() {
        String[] hostPorts = address.split(",");
        Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();
        for(String item : hostPorts) {
            String[] hostPort = item.split(":");
            HostAndPort hostAndPort = new HostAndPort(hostPort[0],Integer.valueOf(hostPort[1]));
            hostAndPorts.add(hostAndPort);
        }
        return hostAndPorts;
    }

    @Override
    public void destroy() throws Exception {
        if (jedisCluster != null) {
            jedisCluster.close();
        }
    }

    public void setJedisPoolConfig(JedisPoolConfig jedisPoolConfig) {
        this.jedisPoolConfig = jedisPoolConfig;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
}
public interface RedisCallback<T> {

    T doInRedis(ShardedJedis jedis);
}
/**
 * Created by shenhongxi on 2018/12/27.
 * 单个redis模式作为sharding模式的特例(配一个host:port即可)
 * JedisCluster不用封装,直接用即可
 */
@Slf4j
public class RedisTemplate {

    private ShardedJedisPool shardedJedisPool;

    private ObjectMapper objectMapper = new ObjectMapper();

    public <T> T execute(RedisCallback<T> action) {
        ShardedJedis jedis = fetchJedis();
        try {
            return action.doInRedis(jedis);
        } finally {
            release(jedis);
        }
    }

    public void set(String key, String value) {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.set(key, value);
        } finally {
            release(jedis);
        }
    }

    public void set(String key, String value, int seconds) {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.setex(key, seconds, value);
        } finally {
            release(jedis);
        }
    }

    public void setIfAbsent(String key, String value) {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.setnx(key, value);
        } finally {
            release(jedis);
        }
    }

    public String get(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.get(key);
        } finally {
            release(jedis);
        }
    }

    public void del(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.del(key);
        } finally {
            release(jedis);
        }
    }

    public List<String> multiGet(Collection<String> keys) {
        List<String> list = new ArrayList<>();
        keys.stream().forEach(key -> list.add(get(key)));
        return list;
    }

    public Long increment(String key, long delta) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.incrBy(key, delta);
        } finally {
            release(jedis);
        }
    }

    public Double increment(String key, double delta) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.incrByFloat(key, delta);
        } finally {
            release(jedis);
        }
    }

    public Long append(String key, String value) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.append(key, value);
        } finally {
            release(jedis);
        }
    }

    public String get(String key, long start, long end) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.getrange(key, start, end);
        } finally {
            release(jedis);
        }
    }

    public Long size(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.strlen(key);
        } finally {
            release(jedis);
        }
    }

    public Boolean setBit(String key, long offset, boolean value) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.setbit(key, offset, value);
        } finally {
            release(jedis);
        }
    }

    public Boolean getBit(String key, long offset) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.getbit(key, offset);
        } finally {
            release(jedis);
        }
    }

    public long sadd(String key, String... values) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.sadd(key, values);
        } finally {
            release(jedis);
        }
    }

    public Set<String> smembers(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.smembers(key);
        } finally {
            release(jedis);
        }
    }

    public boolean sismember(String key, String value) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.sismember(key, value);
        } finally {
            release(jedis);
        }
    }

    public long lpush(String key, String... values) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.lpush(key, values);
        } finally {
            release(jedis);
        }
    }

    public String rpop(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.rpop(key);
        } finally {
            release(jedis);
        }
    }

    public List<String> lrange(String key, long start, long end) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.lrange(key, start, end);
        } finally {
            release(jedis);
        }
    }

    public Long hset(String key, String field, String value) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.hset(key, field, value);
        } finally {
            release(jedis);
        }
    }

    public String hget(String key, String field) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.hget(key, field);
        } finally {
            release(jedis);
        }
    }

    public boolean hexists(String key, String field) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.hexists(key, field);
        } finally {
            release(jedis);
        }
    }

    public long hdel(String key, String... fields) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.hdel(key, fields);
        } finally {
            release(jedis);
        }
    }

    public <T> void set(String key, T value, int seconds) throws Exception {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.setex(key.getBytes(), seconds, this.serialize(value));
        } finally {
            release(jedis);
        }
    }

    public <T> void set(String key, T value) throws Exception {
        ShardedJedis jedis = fetchJedis();
        try {
            jedis.set(key.getBytes(), this.serialize(value));
        } finally {
            release(jedis);
        }
    }

    public <T> T get(String key, Class<T> clazz) {
        byte[] value = this.getBytes(key);
        return this.deserialize(value, clazz);
    }

    public byte[] getBytes(String key) {
        ShardedJedis jedis = fetchJedis();
        try {
            return jedis.get(key.getBytes());
        } finally {
            release(jedis);
        }
    }

    public void setShardedJedisPool(ShardedJedisPool shardedJedisPool) {
        this.shardedJedisPool = shardedJedisPool;
    }

    private ShardedJedis fetchJedis() {
        return shardedJedisPool.getResource();
    }

    private void release(ShardedJedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    private <T> byte[] serialize(T value) throws Exception {
        return objectMapper.writeValueAsBytes(value);
    }

    private <T> T deserialize(byte[] value, Class<T> clazz) {
        try {
            return objectMapper.readValue(value, clazz);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
<!-- Cluster模式 (请搭建redis集群哦,不要client是cluster模式,server还是单点)-->
<!--<bean id="redisClusterClient" class="org.hongxi.whatsmars.redis.client.cluster.RedisClusterClient">
    <property name="address" value="127.0.0.1:6379,127.0.01:7379,127.0.0.1:8379" />
    <property name="timeout" value="3000" />
    <property name="jedisPoolConfig" ref="commonJedisPoolConfig" />
</bean>-->
<!-- 客户端sharding模式 -->
<bean id="shardedRedisClient" class="org.hongxi.whatsmars.redis.client.sharded.ShardedRedisClient">
    <property name="address" value="test1:127.0.0.1:6379,test2:127.0.0.1:6379" />
    <property name="timeout" value="3000" />
    <property name="jedisPoolConfig" ref="commonJedisPoolConfig" />
</bean>

<bean id="redisTemplate" class="org.hongxi.whatsmars.redis.client.RedisTemplate">
    <property name="shardedJedisPool" ref="shardedRedisClient" />
</bean>

<bean id="commonJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="256" />
    <property name="maxIdle" value="8" />
    <property name="minIdle" value="2" />
    <property name="maxWaitMillis" value="3000" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />
    <property name="blockWhenExhausted" value="true" />
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-redis.xml")
public class Demo {

//    @Autowired
    @Qualifier("redisClusterClient")
    private JedisCluster jedisCluster;

    @Autowired
    @Qualifier("shardedRedisClient")
    private ShardedJedisPool shardedRedisClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testCluster() {
        String cacheContent = null;
        try {
            cacheContent = jedisCluster.get("hello_world");
        } catch (Exception e) {
            //如果异常,你可以决定是否忽略
        }
        if(cacheContent == null) {
            //如果cache中不存在,或者redis异常
        }
    }

    @Test
    public void testSharded() {
        ShardedJedis jedis = shardedRedisClient.getResource();
        String cacheContent = null;
        try {
            cacheContent = jedis.get("hello_world");
            System.out.println(cacheContent);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        // 获取redis数据之后,立即归还连接,然后开始进行业务处理
        if(cacheContent == null) {
            // DB operation
        }
        // ..
    }

    @Test
    public void testTemplate() {
        String key = "domain";
        redisTemplate.set(key, "hongxi.org");
        assert "hongxi.org".equals(redisTemplate.get(key));
    }

    @Test
    public void testCallback() {
        String key = "countries";
        redisTemplate.sadd(key, "China", "America", "Japan");
        Long result = redisTemplate.execute((jedis) -> jedis.scard(key));
        assert 3 == result;
    }
}
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.