最近在改造后台项目,使用的springCloud框架,单个服务用的springBoot。有一个业务需求是要连接一个多节点的redis,不是集群,就是多节点的redis,原来的springMVC项目中使用的是单例模式的redisPool来实现的,代码如下:
package com.qlyd.redispool;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.SortingParams;
import com.aspire.boc.util.ResourceManager;
public class BusinessRedisPool {
private final Logger logger = Logger.getLogger(BusinessRedisPool.class);
private ShardedJedisPool jedisPool = null;
private ResourceManager rm = ResourceManager.getInstance();
private static BusinessRedisPool instance = new BusinessRedisPool();
public static BusinessRedisPool getInstance() {
return instance;
}
public BusinessRedisPool() {
if (jedisPool != null) {
jedisPool.close();
}
try {
JedisPoolConfig config = new JedisPoolConfig();
String redis_max_active = rm.getValue("busi_max_active");
config.setMaxTotal(Integer.parseInt(redis_max_active));
String redis_max_idle = rm.getValue("busi_max_idle");
config.setMaxIdle(Integer.parseInt(redis_max_idle));
String redis_max_wait = rm.getValue("busi_max_wait");
config.setMaxWaitMillis(Integer.parseInt(redis_max_wait));
config.setTestOnBorrow(true);
String redis_addr = rm.getValue("busi_redis_addr");
// String redis_port = rm.getValue("busi_redis_port");
String redis_timeout = rm.getValue("busi_redis_timeout");
// config.set
String redis_auth = rm.getValue("busi_redis_auth");
String[] redisArray = redis_addr.split(";");
List<JedisShardInfo> jdsInfoList = new ArrayList<JedisShardInfo>();
for (int i = 0; i < redisArray.length; i++) {
String subAddrStr = redisArray[i];
String[] subAddrArray = subAddrStr.split(":");
JedisShardInfo shardsubInfo = new JedisShardInfo(
subAddrArray[0], Integer.parseInt(subAddrArray[1]));
if (redis_auth != null && !"".equals(redis_auth)) {
shardsubInfo.setPassword(redis_auth);
}
jdsInfoList.add(shardsubInfo);
}
// JedisShardInfo jedisa = new
// JedisShardInfo("192.168.110.236",6380);
//
// JedisShardInfo jedisb = new
// JedisShardInfo("192.168.110.238",6380);
//
// List<JedisShardInfo> jdsInfoList =new
// ArrayList<JedisShardInfo>();
// jdsInfoList.add(jedisa);
// jdsInfoList.add(jedisb);
//
jedisPool = new ShardedJedisPool(config, jdsInfoList);
} catch (Exception e) {
logger.error("后台功能性redis连接池创建失败", e);
}
}
/**
* 获取Jedis实例
*
* @return
*/
public ShardedJedis getJedis() {
try {
if (jedisPool != null) {
ShardedJedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 释放jedis资源
*
* @param jedis
*/
public void returnResource(final ShardedJedis jedis) {
if (jedis != null) {
// jedisPool.returnResource(jedis);
jedis.close();
}
}
public static void main(String[] args) {
ShardedJedis jedis = BusinessRedisPool.getInstance().getJedis();
BusinessRedisPool.getInstance().returnResource(jedis);
}
}
可是在springBoot中,初始化连接池的时候用@Value读取不到配置文件中的值,只能写死在项目中。这样不合理并且自动化部署到不同环境的时候还得修改代码来实现。百度谷歌群里大咖一通讨论,发现springBoot中初始化可以使用另外一种方法:
1.新建一个property类来映射配置文件
package com.rxcm.qlydgateway.common.redis; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * @Author:zhuyumeng * @Description: redis连接池的配置信息类 * @Date:Created in 17:30 2018/3/30 * @Modified: */ @Component @ConfigurationProperties(prefix = "business.redis") @PropertySource("classpath:application-dev.properties") public class BusinessRedisPoolProperties { private String redis_auth; private String redis_addr; private int maxActive;//最打连接数 private int maxWait;//最长等待市场 private int maxIdle;//最大空闲shu public int getMaxActive() { return maxActive; } public void setMaxActive(int maxActive) { this.maxActive = maxActive; } public int getMaxWait() { return maxWait; } public void setMaxWait(int maxWait) { this.maxWait = maxWait; } public int getMaxIdle() { return maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public String getRedis_auth() { return redis_auth; } public void setRedis_auth(String redis_auth) { this.redis_auth = redis_auth; } public String getRedis_addr() { return redis_addr; } public void setRedis_addr(String redis_addr) { this.redis_addr = redis_addr; } }
2.创建redisPoolTemplate
package com.rxcm.qlydgateway.common.redis; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPool; import java.util.ArrayList; import java.util.List; @Configuration public class BusinessRedisTemplate { private final Logger logger = Logger.getLogger(BusinessRedisTemplate.class); @Autowired private BusinessRedisPoolProperties businessRedisPoolProperties; /** * 获取Jedis实例 * * @return */ @Bean public ShardedJedisPool getJedisPool() { ShardedJedisPool jedisPool = null; try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(businessRedisPoolProperties.getMaxActive()); config.setMaxIdle(businessRedisPoolProperties.getMaxIdle()); config.setMaxWaitMillis(businessRedisPoolProperties.getMaxWait()); config.setTestOnBorrow(true); String redis_addr=businessRedisPoolProperties.getRedis_addr(); String[] redisArray = redis_addr.split(";"); String redis_auth=businessRedisPoolProperties.getRedis_auth(); List<JedisShardInfo> jdsInfoList = new ArrayList<JedisShardInfo>(); for (int i = 0; i < redisArray.length; i++) { String subAddrStr = redisArray[i]; String[] subAddrArray = subAddrStr.split(":"); JedisShardInfo shardsubInfo = new JedisShardInfo( subAddrArray[0], Integer.parseInt(subAddrArray[1])); if (redis_auth != null && !"".equals(redis_auth)) { shardsubInfo.setPassword(redis_auth); } jdsInfoList.add(shardsubInfo); } jedisPool = new ShardedJedisPool(config, jdsInfoList); return jedisPool; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 释放jedis资源 * * @param jedis */ public void returnResource(final ShardedJedis jedis) { if (jedis != null) { jedis.close(); } } }
3.在使用的时候直接将resisPoolTemplate注入就可以了
@Resource private BusinessRedisTemplate businessRedisTemplate;
ShardedJedis jedis=null; try{ if(jedis==null){ jedis= businessRedisTemplate.getJedisPool().getResource(); } List<String> userInfoList = jedis.hmget(key,"nickname", "mobile","collectchannel","birthday","credits","exper");
ok,这样就实现了redisPool的初始化及实现方法。
结论:很多场景都可以用这种套路,后期可以将这种方式写成一个jar包,要用到链接池的时候依赖jar,在配置文件中配置一下名字,redis地址就可以直接注入使用。嗯嗯。。写好了再更新