Recently, we are considering using redis’s message queue to solve the problem of high concurrency business scenario of company’s voucher collection and integral exchange. Therefore, we have encountered many exceptions caused by improper use of redis, so we share the solution process of one of the exceptions
Since I was written in Java, I used jedis, version 2.2. At first, I mainly used lpush, rpop, hget and hset in redis for stress testing. There were 100 threads, and each thread had 1000 cycles, so there were few problems. When I use hincr, hsetnx and other operations, after testing for more than ten seconds, there will be a java.net.socketexception: permission denied: connect error. At first, I searched a lot of data, but I seldom mentioned this error. We have to search the standard writing method of redis on the Internet and improve our own redis tool class. Finally, we mainly optimize the code of redis resource return, which was not used in the previous resource return. In the exception capture processing block, we use returnbrokenresource for processing
According to a blog post on the Internet
a. When getting an instance of jedis, there are actually two types of errors
one is pool. Getresource(), which can’t get available jedis instances
the other is jedis.set/get, which will also throw an exception when there is an error
in order to realize the distinction, it is implemented according to whether the instance is null or not. If it is empty, it means that the instance is not initialized at all, and there is no need to return to the pool; If instance is not null, it needs to be returned to pool
b. When there is an error in instance, you must call returnbrokenresource to return it to pool. Otherwise, there may be data in the buffer of instance obtained by getresource next time, which will cause problems
The operation steps of jedis are as follows:
1 – > To get the jedis instance, you need to get it from the jedispool
2-> When the jedis instance is used up, it needs to be returned to jedispool
3-> If there is an error in the use of jedis, you also need to return it to jedispool
public long hsetnx(String key, String field,String value) {
long isExist =0;
ShardedJedis shardedJedis =null;
try {
shardedJedis = (ShardedJedis) shardedJedisPool.getResource();//shardedJedisPool为redis链接池
if(shardedJedis != null){
isExist = shardedJedis.hsetnx(key, field, value);
}
}catch (Exception e) {
closeBroken(shardedJedis);//Mainly add this closeBroken method
e.printStackTrace();
}finally{
close(shardedJedis);
}
return isExist;
}
public void closeBroken(ShardedJedis shardedJedis){
if(shardedJedis!=null&&shardedJedisPool!=null){
shardedJedisPool.returnBrokenResource(shardedJedis);
}
}
public void close(ShardedJedis shardedJedis) {
try {
if(shardedJedis!=null&&shardedJedisPool!=null){
shardedJedisPool.returnResource(shardedJedis);
}
} catch (Exception e) {
e.printStackTrace();
}
}
After the stress test, there is no frequent connection rejection error