-
Notifications
You must be signed in to change notification settings - Fork 614
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;
}
}
wiki.hongxi.org
首页
Java核心技术
- JUC JMM与线程安全
- JUC 指令重排与内存屏障
- JUC Java内存模型FAQ
- JUC 同步和Java内存模型
- JUC volatile实现原理
- JUC AQS详解
- JUC AQS理解
- JUC synchronized优化
- JUC 线程和同步
- JUC 线程状态
- JUC 线程通信
- JUC ThreadLocal介绍及原理
- JUC 死锁及避免方案
- JUC 读写锁简单实现
- JUC 信号量
- JUC 阻塞队列
- NIO Overview
- NIO Channel
- NIO Buffer
- NIO Scatter与Gather
- NIO Channel to Channel Transfers
- NIO Selector
- NIO FileChannel
- NIO SocketChannel
- NIO ServerSocketChannel
- NIO Non-blocking Server
- NIO DatagramChannel
- NIO Pipe
- NIO NIO vs. IO
- NIO DirectBuffer
- NIO zero-copy
- NIO Source Code
- NIO HTTP Protocol
- NIO epoll bug
- Reflection 基础
- Reflection 动态代理
- JVM相关
- 设计模式典型案例
Netty
RocketMQ深入研究
kafka深入研究
Pulsar深入研究
Dubbo源码导读
- Dubbo SPI
- Dubbo 自适应拓展机制
- Dubbo 服务导出
- Dubbo 服务引用
- Dubbo 服务字典
- Dubbo 服务路由
- Dubbo 集群
- Dubbo 负载均衡
- Dubbo 服务调用过程
微服务架构
Redis
Elasticsearch
其他
- Dubbo 框架设计
- Dubbo 优雅停机
- dubbo-spring-boot-starter使用指南
- rocketmq-spring-boot-starter使用指南
- Mybatis multi-database in spring-boot 2
- RocketMQ 客户端简单封装
- Otter 入门
杂谈
关于我