Skip to content

Redis 客户端简单封装

javahongxi edited this page Jul 25, 2019 · 1 revision
<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;
    }
}

首页

Java核心技术

Netty

RocketMQ深入研究

kafka深入研究

Pulsar深入研究

Dubbo源码导读

微服务架构

Redis

Elasticsearch

其他

杂谈

关于我

Clone this wiki locally