-
彻底解决 Jedis 连接池 获取不到连接,连接放回连接池错误的问题
2018-02-11 16:17:58
- public class CacheKit {
- private static Logger logger = LoggerFactory.getLogger(CacheKit.class);
- private List<JSONObject> resultList;
- private static JedisPool pool;
- /**
- * 初始化Redis连接池
- */
- private static void initializePool() {
- //redisURL 与 redisPort 的配置文件
- String configFile = "production.properties";
- if (PropKit.getBoolean("devMode")) {
- configFile = "dev.properties";
- }
- JedisPoolConfig config = new JedisPoolConfig();
- //设置最大连接数(100个足够用了,没必要设置太大)
- config.setMaxTotal(100);
- //最大空闲连接数
- config.setMaxIdle(10);
- //获取Jedis连接的最大等待时间(50秒)
- config.setMaxWaitMillis(50 * 1000);
- //在获取Jedis连接时,自动检验连接是否可用
- config.setTestOnBorrow(true);
- //在将连接放回池中前,自动检验连接是否有效
- config.setTestOnReturn(true);
- //自动测试池中的空闲连接是否都是可用连接
- config.setTestWhileIdle(true);
- //创建连接池
- pool = new JedisPool(config, PropKit.use(configFile).get("redisURL"),
- PropKit.use(configFile).getInt("redisPort"));
- }
- /**
- * 多线程环境同步初始化(保证项目中有且仅有一个连接池)
- */
- private static synchronized void poolInit() {
- if (null == pool) {
- initializePool();
- }
- }
- /**
- * 获取Jedis实例
- */
- private static Jedis getJedis() {
- if (null == pool) {
- poolInit();
- }
- int timeoutCount = 0;
- while (true) {
- try {
- if (null != pool) {
- return pool.getResource();
- }
- } catch (Exception e) {
- if (e instanceof JedisConnectionException) {
- timeoutCount++;
- logger.warn("getJedis timeoutCount={}", timeoutCount);
- if (timeoutCount > 3) {
- break;
- }
- } else {
- logger.warn("jedisInfo ... NumActive=" + pool.getNumActive()
- + ", NumIdle=" + pool.getNumIdle()
- + ", NumWaiters=" + pool.getNumWaiters()
- + ", isClosed=" + pool.isClosed());
- logger.error("GetJedis error,", e);
- break;
- }
- }
- break;
- }
- return null;
- }
- /**
- * 释放Jedis资源
- *
- * @param jedis
- */
- public static void returnResource(Jedis jedis) {
- if (null != jedis) {
- pool.returnResourceObject(jedis);
- }
- }
- /**
- * 绝对获取方法(保证一定能够使用可用的连接获取到 目标数据)
- * Jedis连接使用后放回
- * @param key
- * @return
- */
- private String safeGet(String key) {
- Jedis jedis = getJedis();
- while (true) {
- if (null != jedis) {
- break;
- } else {
- jedis = getJedis();
- }
- }
- String value = jedis.get(key);
- returnResource(jedis);
- return value;
- }
- /**
- * 绝对设置方法(保证一定能够使用可用的链接设置 数据)
- * Jedis连接使用后返回连接池
- * @param key
- * @param time
- * @param value
- */
- private void safeSet(String key, int time, String value) {
- Jedis jedis = getJedis();
- while (true) {
- if (null != jedis) {
- break;
- } else {
- jedis = getJedis();
- }
- }
- jedis.setex(key, time, value);
- returnResource(jedis);
- }
- /**
- * 绝对删除方法(保证删除绝对有效)
- * Jedis连接使用后返回连接池</span>
- * @param key
- */
- private void safeDel(String key) {
- Jedis jedis = getJedis();
- while (true) {
- if (null != jedis) {
- break;
- } else {
- jedis = getJedis();
- }
- }
- jedis.del(key);
- returnResource(jedis);
- }
- /**自定义的一些 get set del 方法,方便使用**/
- public JSONObject getByCache(String key) {
- String result = safeGet(key);
- if (result != null) {
- return (JSONObject) JSONObject.parse(result);
- }
- return null;
- }
- public String getByCacheToString(String key) {
- String result = safeGet(key);
- if (result != null) {
- return result;
- }
- return null;
- }
- public List<JSONObject> getArrayByCache(String key) {
- String result = safeGet(key);
- if (result != null) {
- resultList = JSONArray.parseArray(result, JSONObject.class);
- return resultList;
- }
- return null;
- }
- public JSONArray getJSONArrayByCache(String key) {
- String result = safeGet(key);
- if (result != null) {
- return JSONArray.parseArray(result);
- }
- return null;
- }
- public void setByCache(String key, String s) {
- safeSet(key, 86400, s);
- }
- public void setByCacheOneHour(String key, String s) {
- safeSet(key, 3600, s);
- }
- public void setByCacheOneHour(String key, List<JSONObject> json) {
- safeSet(key, 86400, JSONObject.toJSONString(json));
- resultList = json;
- }
- public void setByCache(String key, JSONObject json) {
- safeSet(key, 86400, JSONObject.toJSONString(json));
- }
- public void setByCache(String key, List<JSONObject> list) {
- safeSet(key, 86400, JSONObject.toJSONString(list));
- resultList = list;
- }
- public void setByCache(String key, JSONArray array) {
- safeSet(key, 86400, JSONArray.toJSONString(array));
- }
- public void setByCacheCusTime(String key, String s, int time) {
- safeSet(key, time, s);
- }
- public void delByCache(String key) {
- if (null != safeGet(key)) {
- safeDel(key);
- }
- }
- public JSONObject toJSON(DBObject db) {
- return (JSONObject) JSONObject.toJSON(db);
- }
- public List<JSONObject> toJSON(List<DBObject> list) {
- List<JSONObject> json = new ArrayList<>();
- for (DBObject aList : list) {
- json.add((JSONObject) JSONObject.toJSON(aList));
- }
- return json;
- }
- public boolean notNull() {
- return resultList != null && resultList.size() > 0;
- }
- public List<JSONObject> getResult() {
- return resultList;
- }
- }
-
jedispool 连 redis 高并发卡死
2018-02-11 16:12:06
https://www.2cto.com/kf/201504/395403.html
java端在使用jedispool 连接redis的时候,在高并发的时候经常卡死,或报连接异常,JedisConnectionException,或者getResource 异常等各种问题
在使用jedispool 的时候一定要注意两点
1。 在获取 jedisPool和jedis的时候加上线程同步,保证不要创建过多的jedispool 和 jedis
2。 用完Jedis实例后需要返还给JedisPool
整理了一下redis工具类,通过大量测试和高并发测试的
package
com.caspar.util;
import
org.apache.log4j.Logger;
import
redis.clients.jedis.Jedis;
import
redis.clients.jedis.JedisPool;
import
redis.clients.jedis.JedisPoolConfig;
/**
* Redis 工具类
* @author caspar
*/
public
class
RedisUtil {
protected
static
Logger logger = Logger.getLogger(RedisUtil.
class
);
//Redis服务器IP
private
static
String ADDR_ARRAY = FileUtil.getPropertyValue(
"/properties/redis.properties"
,
"server"
);
//Redis的端口号
private
static
int
PORT = FileUtil.getPropertyValueInt(
"/properties/redis.properties"
,
"port"
);
//访问密码
// private static String AUTH = FileUtil.getPropertyValue("/properties/redis.properties", "auth");
//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private
static
int
MAX_ACTIVE = FileUtil.getPropertyValueInt(
"/properties/redis.properties"
,
"max_active"
);;
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private
static
int
MAX_IDLE = FileUtil.getPropertyValueInt(
"/properties/redis.properties"
,
"max_idle"
);;
//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private
static
int
MAX_WAIT = FileUtil.getPropertyValueInt(
"/properties/redis.properties"
,
"max_wait"
);;
//超时时间
private
static
int
TIMEOUT = FileUtil.getPropertyValueInt(
"/properties/redis.properties"
,
"timeout"
);;
//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private
static
boolean
TEST_ON_BORROW = FileUtil.getPropertyValueBoolean(
"/properties/redis.properties"
,
"test_on_borrow"
);;
private
static
JedisPool jedisPool =
null
;
/**
* redis过期时间,以秒为单位
*/
public
final
static
int
EXRP_HOUR =
60
*
60
;
//一小时
public
final
static
int
EXRP_DAY =
60
*
60
*
24
;
//一天
public
final
static
int
EXRP_MONTH =
60
*
60
*
24
*
30
;
//一个月
/**
* 初始化Redis连接池
*/
private
static
void
initialPool(){
try
{
JedisPoolConfig config =
new
JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool =
new
JedisPool(config, ADDR_ARRAY.split(
","
)[
0
], PORT, TIMEOUT);
}
catch
(Exception e) {
logger.error(
"First create JedisPool error : "
+e);
try
{
//如果第一个IP异常,则访问第二个IP
JedisPoolConfig config =
new
JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool =
new
JedisPool(config, ADDR_ARRAY.split(
","
)[
1
], PORT, TIMEOUT);
}
catch
(Exception e2){
logger.error(
"Second create JedisPool error : "
+e2);
}
}
}
/**
* 在多线程环境同步初始化
*/
private
static
synchronized
void
poolInit() {
if
(jedisPool ==
null
) {
initialPool();
}
}
/**
* 同步获取Jedis实例
* @return Jedis
*/
public
synchronized
static
Jedis getJedis() {
if
(jedisPool ==
null
) {
poolInit();
}
Jedis jedis =
null
;
try
{
if
(jedisPool !=
null
) {
jedis = jedisPool.getResource();
}
}
catch
(Exception e) {
logger.error(
"Get jedis error : "
+e);
}
finally
{
returnResource(jedis);
}
return
jedis;
}
/**
* 释放jedis资源
* @param jedis
*/
public
static
void
returnResource(
final
Jedis jedis) {
if
(jedis !=
null
&& jedisPool !=
null
) {
jedisPool.returnResource(jedis);
}
}
/**
* 设置 String
* @param key
* @param value
*/
public
static
void
setString(String key ,String value){
try
{
value = StringUtil.isEmpty(value) ?
""
: value;
getJedis().set(key,value);
}
catch
(Exception e) {
logger.error(
"Set key error : "
+e);
}
}
/**
* 设置 过期时间
* @param key
* @param seconds 以秒为单位
* @param value
*/
public
static
void
setString(String key ,
int
seconds,String value){
try
{
value = StringUtil.isEmpty(value) ?
""
: value;
getJedis().setex(key, seconds, value);
}
catch
(Exception e) {
logger.error(
"Set keyex error : "
+e);
}
}
/**
* 获取String值
* @param key
* @return value
*/
public
static
String getString(String key){
if
(getJedis() ==
null
|| !getJedis().exists(key)){
return
null
;
}
return
getJedis().get(key);
}
}
-
Ant将Jmeter的jtl文件转为html文件报“前言中不允许有内容”
2018-02-07 09:58:49
- 在JMeter的bin目录中找到jmeter.properties;
- 将文件中#jmeter.save.saveservice.output_format=csv改为jmeter.save.saveservice.output_format=xml
注意:去掉前面的#号,后面的xml要小写
-
Jmeter Random Variable配置项可以为每个线程生成随机变量
2018-02-05 11:35:44
配置元件Random Variable可以配置生成随机数,自定义输出格式,最大最小值,以及是否为每个线程单独生成:
Variable Name: uuid Output Format: 12345678-1234-4444-a123-000000000000 Minimum Value: 111111111111 Maximum Value: 999999999999
Seed for Random function:${__Random(1,10,)} //如果指定为一个固定值,则每次迭代,各个线程得到的随机值都会相同
Per Thread (User): True //每个线程生成一个随机数 -
(JMeter/Ant/Jenkins)自动化接口测试的部署 及 部署过程中的坑
2018-02-01 10:43:07
JMeter在nonui方式下的错误:Error in NonGUIDriver java.lang.RuntimeException: Could not find the TestPlan class的处理
http://www.xmeter.net/wordpress/?p=124第一篇:JMeter实现接口/性能自动化(JMeter/Ant/Jenkins)
https://www.cnblogs.com/qmfsun/p/5919603.html
Ant+Jmeter自动化接口测试的部署 及 部署过程中的坑
标题搜索
我的存档
数据统计
- 访问量: 282443
- 日志数: 198
- 建立时间: 2008-08-25
- 更新时间: 2019-11-01