使用Jedis在高并發(fā)報(bào)錯 (java.net.SocketException: Connection reset by peer: socket write error)
1.報(bào)錯信息
java.lang.reflect.InvocationTargetException: null
at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
....
at java.lang.Thread.run(Unknown Source)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset by peer: socket write error
at redis.clients.jedis.Connection.flush(Connection.java:334)
at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:257)
at redis.clients.jedis.BinaryJedis.get(BinaryJedis.java:244)
......
... 15 common frames omitted
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:52)
at redis.clients.util.RedisOutputStream.flush(RedisOutputStream.java:216)
at redis.clients.jedis.Connection.flush(Connection.java:331)
... 22 common frames omitted
Connection reset by peer: socket write error錯誤分析:
常出現(xiàn)的Connection reset by peer: 原因可能是多方面的丽惭,不過更常見的原因是:
①:服務(wù)器的并發(fā)連接數(shù)超過了其承載量蔚携,服務(wù)器會將其中一些連接Down掉;
②:客戶關(guān)掉了瀏覽器,而服務(wù)器還在給客戶端發(fā)送數(shù)據(jù)军俊;
③:瀏覽器端按了Stop
所以本問題是由 ①造成的
修改之前的代碼
初始化jedis的代碼
/**
* 在多線程環(huán)境同步初始化
*/
private static synchronized void poolInit() {
if (pool == null) {
createJedisPool();
}
}
* 獲取一個(gè)jedis 對象
*
* @return
*/
public static Jedis getJedis() {
if (pool == null) {
poolInit();
}
return pool.getResource();
}
使用jedis的代碼
private static Jedis jedis = JedisPoolUtil.getJedis();
public static Object getObject(String key) {
if(exists(key)){
return deserialize(jedis.get(key.getBytes()));
}
return null;
}
修改之后的代碼
初始化jedis的代碼
/**
* 獲取一個(gè)jedis 對象
*
* @return
*/
public static Jedis getJedis() {
if (pool == null) {
poolInit();
}
//如果沒有以下代碼會造成初始化的jedis拿不到 jedis對象
Jedis jedis = null;
try {
if (pool != null) {
jedis = pool.getResource();
}
}
catch (Exception e) {
logger.error("獲取redis失敗 : {}" + ExceptionUtils.getStackTrace(e));
}
return jedis;
}
使用jedis的代碼
/**
* 讀取對象
*
* @param key
* @return
*/
public static Object getObject(String key) {
if (exists(key)) {
//初始化jedis用完之后關(guān)閉連接
Jedis jedis = JedisPoolUtil.getJedis();
Object object = deserialize(jedis.get(key.getBytes()));
jedis.close();
return object;
}
return null;
}